Likelihood Review
Let \(\theta\) be an unknown
parameter or a vector of unknown parameters. Assume that \(\{X_1, X_2, \cdots, X_n \}\) is a set of
IID random variables with distribution \(F(x;
\theta)\). When the distribution is discrete, the probability
mass function (PMF) is used in the likelihood function. If the
distribution is continuous, the probability distribution density
function (PDF) is used in the likelihood function.
We only focus on continuous distributions in this series of research
tutorials. In the rest of this note, we assume \(\{X_1, X_2, \cdots, X_n \}\) is a set of
IID continuous random variables with density function \(f(x; \theta)\). Discrete
distributions such as binomial and Posson distributions are used
occasionally to explain some concepts.
Recall that the likelihood of observing an IID random sample \(\{x_1, x_2, \cdots, x_n \}\) from the
distribution with density function \(f(x;\theta)\) is given by
\[
L(\theta| \mathbf{x}) = \prod_{i = 1}^n f(x_i: \theta)
\]
The MLE of \(\theta\), denoted by
\(\hat{\theta}\) is te solution to the
optimization problem
\[
\hat{\theta} = \arg \max_{\theta \in \Omega} L(\theta: \mathbf{x}).
\]
Since the logarithm of the likelihood is easier to handle in
mathematics, we define the above optimization problem using the
log-likelihood, that is
\[
\hat{\theta} = \arg\max_{\theta \in \Omega} l(\theta: \mathbf{x}),
\]
where \(l(\theta: \mathbf{x}) = \log
[L(\theta: \mathbf{x})]\).
The method of moment (MM) and the maximum likelihood estimation (MLE)
provide a single estimated value from a random sample to approximate the
unknown parameter. This estimation is called point
estimation. This note will focus on inferences based on
MLE.
Some Basic
Concepts
We briefly review some of the concepts introduced in an earlier
note.
Parameter and Statistic: A parameter is a numerical
characteristic of a population. A statistic is a numerical value
calculated from a sample taken from the population.
Estimation, Estimator, and Estimate: An estimation
is a method. An estimator is a formula or function defined based on a
data set. An estimate is a value calculated using the formula (i.e.,
estimator) from the data set.
Point Estimate: a point estimate is a single value
used to estimate the population parameter. It is a random number because
the sample is random.
Interval estimate: an interval estimate is a range
(interval) of values that contains the true value of the unknown
parameter.
Remark - The point estimate is only a descriptive
statistic based on the sample, not the population. For example, when
considering the average starting salaries of recent statistics graduates
at a university, we take a random sample of students and calculate the
average salary, say $55,000. We can not say the average starting salary
of all statistics graduates at the university is $55,000. A better way
to describe the starting salary of the population of statistics
graduates is that the starting salary is around $55,000
- This is a range! That is, we need an interval estimate to
generalize the information from the sample to the population -
confidence interval method!
Interval Estimates
One issue with a point estimate is that it has information about
accuracy and precision. When we say the value of the population
parameter is close to the sample statistics, but we don’t know how close
it is, and how close is considered as close. This section
introduces the general framework to derive the confidence interval for a
population parameter \(\theta\) based
on its point estimate \(\hat{\theta}\)
with the assumption that \(\hat{\theta}\) has a known density \(f(\hat{\theta})\).
We consider imposing a bound to the absolution estimation error \(\epsilon = |\hat{\theta} - \theta| <
b\), we can then calculate the probability
\[
P(|\hat{\theta} - \theta| < b) = P(\theta - b <\hat{\theta}
<\theta + b ) = \int_{\theta-b}^{\theta +b} f(\hat{\theta})
d\hat{\theta} = p_0
\]
The above \(p_0\) is the derived
probability that the absolute estimation error is bounded by given \(b\) with \(\theta\) being known. Under these
assumptions, the inequality \(\theta - b
<\hat{\theta} <\theta + b\) in the middle of the above
equation tells how the point estimate is close to the parameter with
probability \(p_0\). That is,
with known \(\theta, b\), and \(f_{\hat{\theta}}(\cdot)\), we can calculate
the probability that \(\hat{\theta}\)
falls into interval \((\theta - b, \theta
+b)\).
Next, we look at the above equation under different assumptions:
assume we choose the value of \(p_0\),
say \(p_0 = 0.95 = 95\%\). \(\hat{\theta}\) is calculated from a random
sample and \(b\) is a known error
bound. Note that the above equation can re-expressed into the following
form
\[
P(|\hat{\theta} - \theta| < b) = P(\hat{\theta} - b <\theta
<\hat{\theta} + b )= p_0.
\]
The above equation says that the random interval \((\hat{\theta} - b, \hat{\theta} + b )\) has
\(100p_0\%\) chance to include the true
value of the parameter - This is the confidence interval with confidence
level \(100p_0\% = 95\%\) with the
choice of \(p_0 = 0.95\).
One piece of information that needs to be addressed is how to
get \(b\) in the above
discussion.
In one-sample confidence intervals of the population mean, we use
either the central limit theorem of the strong assumption of normality
of the population, the sample mean as the point estimate of the
population mean \(\mu\) has a normal
distribution, then b is the margin of error (i.e., absolution error
bound of point estimation) that has the following form
\[
b = Z_{1-\alpha/2} \frac{s}{\sqrt{n}}
\]
where \(\alpha = 1 - \text{given confidence
level}\) which is called the significance level in testing
hypotheses. \(Z_{1-\alpha/2}\) is the
quantile of the distribution of point estimate \(\hat{\mu} = \bar{X}\) which is normal in
the one sample confidence of population mean.
Therefore, the critical information required in deriving the
confidence interval of a population parameter is the distribution of the
point estimate of the parameter. It is customarily called the sampling
distribution of the point estimate.
Sampling Distribution
of MLE
Recall the central limit theorem concerning the distribution of
sample means we introduced in the elementary statistics:
Central Limit Theorem
Assume that a random sample \(\{x_1,
x_2, \cdots, x_n \}\) is taken from a population with mean \(\mu\) and standard deviation \(\sigma\). Define \(\bar{X} = \sum_{i =1}^n x_i / n\) to be the
point estimate of population mean \(\mu\). If the sample is large, \(\bar{X} \sim N(\mu,
\sigma/\sqrt{n})\)
Remark: The central limit theorem (CLT) does
not assume a specific distribution of the population but
unknown mean \(\mu\) and variance \(\sigma^2\). The only vague condition is
that the sample size is large. Any results derived from the CLT
are called large sample (asymptotic) results.
One of the objectives of this note is to develop asymptotic results
for the MLE that are similar to the above CLT so that we can make
statistical inferences such as constructing confidence intervals and
testing hypotheses. In the next few sections, we introduce the building
blocks to be used in the MLE-based inferences.
Basic Set-up and
Notations
Let \(\{x_1, x_2, \cdots, x_n \}
\stackrel{\text{i.i.d}}{\sim} f_\theta(x)\), \(\theta = (\theta_1, \theta_2, \cdots,
\theta_k)\) is a vector of \(k\)
parameters (could be a single parameter when \(k = 1\)). The likelihood of observing the
data is given by
\[
L(\theta) = \prod_{i=1}^n f_\theta(x_i)
\]
with corresponding log-likelihood function in the following
\[
l(\theta) = \sum_{i=1}^n \log f_\theta (x_i).
\]
Gradient Vector and
Score Equations
The system of score equations is given by
\[
\begin{cases}
\frac{\partial l(\theta)}{\partial \theta_1} = 0 , \\
\frac{\partial l(\theta)}{\partial \theta_2} = 0, \\
\cdots \cdots \cdots \\
\frac{\partial l(\theta)}{\partial \theta_k} = 0.
\end{cases}
\] The above system can be written in the following form
\[
\frac{\partial l(\theta)}{\partial \theta} = \mathbf{0} \ \ \text{ or }
\ \ \nabla_\theta l(\theta) = \mathbf{0}
\]
The mathematical notation \(\nabla\)
(read /’na.bla/) is a differential operator. It is commonly
used in Calculus.
The gradient vector of \(l(\theta)\)
is defined to be
\[
\nabla_\theta l(\theta) = \left( \frac{\partial l(\theta)}{\partial
\theta_1}, \frac{\partial l(\theta)}{\partial \theta_2}, \cdots ,
\frac{\partial l(\theta)}{\partial \theta_k}\right)
\]
Expected Value of
Score Functions
To derive the asymptotic normality of the MLE, we need to use the
following result from advanced real analysis: the order of
differentiation and integration is exchangeable. The proof of general
results requires more advanced mathematical tools in the abstract
measure theory (to be covered in the doctoral-level real analysis
course).
Lemma 1: Suppose that \(f(x,\theta)\) is differentiable in \(\theta\) and there exists a function \(g(x,\theta)\) such that
\(\big| \frac{\partial f(x,
\vartheta)}{\partial \vartheta} \big| \le g(x, \theta)\) for all
\(x\) and \(\theta\) such that \(|\vartheta - \theta|\le
\delta_0\);
\(\int_{-\infty}^\infty g(x, \theta) dx
< \infty\) for all \(\theta\).
Then
\[\frac{d}{d\theta} \int_{-\infty}^\infty
f(x,\theta) dx = \int_{-\infty}^\infty \frac{\partial f(x,
\theta)}{\partial \theta} dx.
\]
We will not prove the lemma in this note. For the likelihood
function, the regularity conditions are satisfied. So we can use the
lemma in statistical inference.
Fact. The expected value of the score function is
equal to zero.
Proof: We will use the definition of expectation and
the above lemma in the following proof. Without loss of generality, we
consider the log-likelihood of observing a single data point \(f(x:\theta)\) and assume \(\theta\) to be a univariate parameter.
\[
E\left[ \frac{\partial \log f(x, \theta)}{\partial \theta} \right]
\stackrel{\text{def}}{=} \int_{-\infty}^\infty \frac{\partial \log f(x,
\theta)}{\partial \theta} f(x, \theta) dx
\]
\[
= \int_{-\infty}^\infty \left[\frac{\partial f(x, \theta)/\partial
\theta}{f(x,\theta)}\right] f(x, \theta) dx = \int_{-\infty}^\infty
\frac{\partial f(x, \theta)}{\partial \theta} dx
\]
\[
\stackrel{\text{switch}}{=} \frac{\partial}{\partial \theta}
\int_{-\infty}^\infty f(x, \theta) dx = \frac{\partial}{\partial \theta}
(1) = 0.
\]
Remarks Lemma 1 introduced in this subsection is
related to several big theorems in mathematics (advanced
calculus and real analysis).
The two conditions in Lemma 1 are also called regularity
conditions. Many statistical theorems (or procedures) require some
regularity conditions needed in mathematical proofs and derivations.
Make sure that the regularity conditions are satisfied in practical
applications.
If the integral is definite with scalar integral limits, then
above Lemma 1 is a special case of Leibniz Rule in
Calculus.
More general forms of the above Lemma 1 are introduced in the
real analysis textbooks under various convergence theorems such as
Lebesgue Dominant Convergence (i.e., bounded convergence
theorem) and Monotone convergence theorem.
Since the derivative is the limit of the rate of change
(instantaneous rate), there is also a rule of exchange in the order of
integral and limit.
The integral is also viewed as an infinite sum, there is
also a rule of exchange of the order of summation and derivative (or
summation and limit).
These types of exchange order
operations are frequently used in statistics deriving asymptotic
statistical results.
To conclude this subsection, we use the same idea in Lemma 1 to
derive the following Lemma concerning the second-order derivative of the
log-likelihood function. Lemma 2 links the two definitions of the
Fisher Information to be introduced in the next
subsection.
Lemma 2: Under some similar regularity conditions
(as stated in Lemma 1), we have
\[
E\left[ \frac{\frac{\partial^2}{\partial
\theta^2}f(x,\theta)}{f(x,\theta)}\right] = 0.
\]
Proof: Using the definition of expectation and the
exchange of the order of the derivative and the integral, we have
\[
E\left[ \frac{\frac{\partial^2}{\partial
\theta^2}f(x,\theta)}{f(x,\theta)}\right] = \int \left[
\frac{\frac{\partial^2}{\partial
\theta^2}f(x,\theta)}{f(x,\theta)}\right] f(x,\theta)dx
\]
\[
= \int \frac{\partial^2}{\partial \theta^2}f(x,\theta) dx
\stackrel{\text{switch}}{=} \frac{\partial^2}{\partial \theta^2} \int
f(x,\theta) dx = \frac{\partial^2}{\partial \theta^2} (1) = 0.
\]
Fisher Information
Matrix
The information on the variance and covariance of the
MLE is contained in the Fisher information matrix. It must be
explicitly specified when making inferences about the MLE of model
parameters. To better understand the concept, we start with the case
with single-parameter models.
Fisher Information
Number
Assume that \(\theta\) is a
univariate parameter of the population with density \(f(x,\theta)\). Let \(\{x_1, x_2, \cdots, x_n \} \sim f(x,
\theta)\) be an IID sample. We use vector \(\mathbf{x}\) to denote the set of random
samples. The log-likelihood of observing the data is a function of \(\theta\) that has the following form
\[
l(\theta:\mathbf{x}) = \log L(\theta: \mathbf{x}) = \sum_{i=1}^n \log
f(x_i, \theta).
\]
The Fisher Information Number based on a random
sample with size \(n\) is defined to be
of the following form
\[
I_n(\theta) \stackrel{\text{def}}{=} E_{\mathbf{x}}\left[
\left(\frac{\partial}{\partial \theta} \log L(\mathbf{x}, \theta)
\right)^2\right].
\]
Lemma 1 in the previous subsection says that
\[
E_X\left[ \frac{\partial}{\partial \theta} f(X_i, \theta)\right] = 0 \ \
\text{for} \ \ i = 1, 2, \cdots, n.
\]
Therefore,
\[
\left\{E_{\mathbf{x}}\left[ \frac{\partial}{\partial \theta}
\sum_{i=1}^n \log f(x_i, \theta)\right] \right\}^2 =\left\{
E_{\mathbf{x}}\left[ \frac{\partial }{\partial \theta} \log L(\theta:
\mathbf{x})\right] \right\}^2 = 0
\]
Using the formula \(\text{Var}(X) = E(X^2)
- [E(X)]^2\) for all random variable \(X\), we have
\[
I_n(\theta) \stackrel{\text{def}}{=} E_{\mathbf{x}}\left[
\left(\frac{\partial}{\partial \theta} \log L( \theta: \mathbf{x})
\right)^2\right] - \left\{E_{\mathbf{x}}\left[ \frac{\partial}{\partial
\theta} \log L(\theta: \mathbf{x})\right] \right\}^2 =
\text{Var}_{\mathbf{x}}\left[\log L(\theta: \mathbf{x})\right].
\]
This means that the Fisher Information \(I_n(\theta)\) is the variance of the score
function.
Next, we present an alternative definition of the Fisher Information.
Note that
\[
\frac{\partial^2}{\partial \theta^2}\left[ \log L(\theta: \mathbf{x})
\right] = \frac{\partial}{\partial \theta} \left\{ \frac{\partial
}{\partial \theta} \left[ \log L( \theta: \mathbf{x})\right]\right\}
=\frac{\partial}{\partial \theta} \left\{ \left[ \frac{\partial
L(\theta: \mathbf{x})/\partial \theta}{L(\theta:
\mathbf{x})}\right]\right\}
\] Using the multiplicative rule of derivative, we have
\[
=
\frac{L(\theta:\mathbf{x})\frac{\partial^2}{\partial\theta^2}L(\theta:\mathbf{x})
-
\left[\frac{\partial}{\partial\theta}L(\theta:\mathbf{x})\right]^2}{L^2(\theta:
\mathbf{x})}
\]
\[
=\frac{\frac{\partial^2}{\partial\theta^2}L(\theta:\mathbf{x})
}{L(\theta: \mathbf{x})} -
\left[\frac{\frac{\partial}{\partial\theta}L(\theta:\mathbf{x})
}{L(\theta: \mathbf{x})}\right]^2.
\]
From Lemma 2, the first term of the above equation is zero.
Therefore,
\[
\frac{\partial^2}{\partial \theta^2}\left[ \log L(\theta: \mathbf{x})
\right] = -
\left[\frac{\frac{\partial}{\partial\theta}L(\theta:\mathbf{x})
}{L(\theta: \mathbf{x})}\right]^2.
\]
This means we can also define the Fisher Information number can also
be derived as
\[
I_n(\theta) = - E \left\{\frac{\partial^2}{\partial \theta^2}\left[ \log
L(\theta: \mathbf{x}) \right]\right\}.
\]
This means that the Fisher Information number is the negative
expectation of the second-order derivative of the log-likelihood.
Since we assume an IID sample in most cases, we can derive the
relationship between the Fisher information number associated with the
entire observed data set and that based on the individual observation in
the data set. Denote \(I_0(\theta)\) as
the Fisher information number of a single observation of an IID
sample.
\[
I_n(\theta) = - E \left\{\frac{\partial^2}{\partial \theta^2}\left[ \log
L(\theta: \mathbf{x}) \right]\right\} =
-E\left\{\frac{\partial^2}{\partial \theta^2}\left[\sum_{i=1}^n \log
f(\theta: x_i) \right]\right\}
\]
\[
= \sum_{i=1}^n \left\{- E\left[\frac{\partial^2}{\partial
\theta^2} \log f(\theta: x_i) \right] \right\} = nI_0(\theta).
\]
Remarks Some comments on the Fisher Information:
The Fisher information is only a function of the parameter since
it is defined as an expectation (with respect to \(\mathbf{X}\)) of the
log-likelihood.
If we replace the parameter with an estimated one such as MLE, we
obtain \(\widehat{I_n(\theta)} =
I_n(\hat{\theta})\). \(\widehat{I_n(\theta)}\) is called observed
Fisher information number!
The Fisher information number is
always positive.
The Fisher information number is dependent on the sample size.
This will be used in developing the asymptotic normality for the MLE in
the next section.
Example: Consider an IID sample \(\{x_1, x_2, \cdots, x_n\} \sim f(x,\theta) =
\theta e^{-\theta x}\). Find the Fisher information number.
Note that the log-likelihood function of \(\theta\) is given by
\[
l(\theta: \mathbf{x}) = n \log \theta -\theta \sum_{i=1}^n x_i.
\]
The second order derivative of \(l(\theta)\) with respect to \(\theta\) is
\[
\frac{\partial^2}{\partial \theta^2} l(\theta) =
\frac{\partial}{\partial \theta}\left( \frac{n}{\theta} - \sum_{i=1}^n
x_i \right) = -\frac{n}{\theta^2}.
\]
By definition,
\[
I_n(\theta) = -E\left( \frac{\partial^2}{\partial \theta^2} l(\theta,
\mathbf{x})\right) = -E(-\frac{n}{\theta^2}) = \frac{n}{\theta^2}.
\]
The exponential density function has another form (i.e.,
reparametrization) \(f(x,\beta) =
\frac{1}{\beta} e^{-x/\beta}\). A natural question is whether we
need to repeat the same calculation in the above example to find the
Fisher information \(I_n(\beta)\). The
answer is unnecessary. We can reparametrization in the Fisher
information number.
Let \(\eta = \psi(\theta)\) and
\(\psi(\cdot)\) is invertible, that is,
\(\theta = \psi^{-1}(\eta)\) exists.
Assume that two density forms of \(X\)
are \(f(x, \theta)\) and \(g(x, \eta)\). Clearly, \(g(x, \eta) = f(x, \psi^{-1}(\eta))\)
(why?). Assume further that \(I_n(\theta) = I_n[\psi^{-1}(\eta)]\) is
known.
Due to reparametrization, the same random variable has different
forms of density function. When we work on the expectation with the
random variable, we should specify the associated density function.
Next, we express \(I_g(\eta)\) with
respect to \(I_f(\theta)\).
\[
I_{n,g}(\eta) = E_g\left[ \left(\frac{\partial}{\partial \eta} \log g(x,
\eta) \right)^2 \right] = E_g\left[ \left(\frac{\partial}{\partial
\eta} \log f(x, \psi^{-1}(\eta)) \right)^2 \right]
\]
\[
= E_g\left[ \left(\frac{\partial}{\partial \eta} \log f(x,
\psi^{-1}(\eta)) \times \frac{\partial}{\partial \eta}
\psi^{-1}(\eta)\right)^2 \right]
\]
\[
= E_g\left[ \left(\frac{\partial}{\partial \eta} \log f(x,
\psi^{-1}(\eta)) \right)^2 \times \left(\frac{\partial}{\partial \eta}
\psi^{-1}(\eta)\right)^2 \right]
\]
\[
= E_g\left[ \left(\frac{\partial}{\partial \eta} \log f(x,
\psi^{-1}(\eta)) \right)^2 \right]\times \left(\frac{\partial}{\partial
\eta} \psi^{-1}(\eta)\right)^2 = I_{n,f}(\theta)\times
\left(\frac{\partial}{\partial \eta} \psi^{-1}(\eta)\right)^2.
\]
That is,
\[
I_{n,g}(\eta)=I_{n,f}(\theta)\times \left(\frac{\partial}{\partial \eta}
\psi^{-1}(\eta)\right)^2.
\]
Fisher Information
Matrix
For multi-parameter models (distributions), we need a Fisher
information matrix to characterize the covariance structure of the MLE
of the vector of multiple parameters. Denote \(f(x; \mathbf{\theta})\) be the density
function of \(X\) with a k-dimensional
parameters \(\mathbf{\theta} = (\theta_1,
\theta_2, \cdots, \theta_k)\) (Caution:
if not specified, all vectors in this series of note are column vectors.
This is also true in most mathematics and statistics books and
literature)
Under the same setup, the likelihood function of observing \(\{x_1, x_2, \cdots, x_n \}\sim f(x,
\mathbf{\theta})\) is given by
\[
L(\mathbf{\theta}:\mathbf{x}) = \prod_{i=1}^n f(x_i, \mathbf{\theta})
\]
The gradient vector of the log-likelihood is
\[
\frac{\partial}{\partial \theta} \log L(\theta, \mathbf{x}) = \left(
\frac{\partial}{\partial \theta_1} \log L(\theta,
\mathbf{x}), \frac{\partial}{\partial \theta_2} \log L(\theta,
\mathbf{x}), \cdots, \frac{\partial}{\partial \theta_k} \log L(\theta,
\mathbf{x}),\right).
\]
Denote
\[
\frac{\partial}{\partial \theta^T} \log L(\theta, \mathbf{x}) = \left(
\frac{\partial}{\partial \theta_1} \log L(\theta,
\mathbf{x}), \frac{\partial}{\partial \theta_2} \log L(\theta,
\mathbf{x}), \cdots, \frac{\partial}{\partial \theta_k} \log L(\theta,
\mathbf{x}),\right)^T
\]
The Fisher information matrix of the k-dimensional
parameter \(\theta\) is defined to
be
\[
\mathbb{I}_n(\mathbf{\theta}) = E\left( \frac{\partial}{\partial \theta}
\log L(\theta, \mathbf{x})\frac{\partial}{\partial \theta^T} \log
L(\theta, \mathbf{x}) \right).
\]
The explicit matrix form of the two-parameter case is
\[
\mathbb{I}_n(\mathbf{\theta}) = E \left[\left( \frac{\partial}{\partial
\theta_1} \log L(\theta, \mathbf{x}), \frac{\partial}{\partial \theta_2}
\log L(\theta, \mathbf{x}) \right) \left( \frac{\partial}{\partial
\theta_1} \log L(\theta, \mathbf{x}), \frac{\partial}{\partial \theta_2}
\log L(\theta, \mathbf{x}) \right)^T\right]
\]
\[
= E \begin{bmatrix}
\left(\frac{\partial}{\partial \theta_1} \log L(\theta, \mathbf{x})
\right)^2 & \frac{\partial}{\partial \theta_1} \log L(\theta,
\mathbf{x})\frac{\partial}{\partial \theta_2} \log L(\theta,
\mathbf{x}) \\
\frac{\partial}{\partial \theta_1} \log L(\theta,
\mathbf{x})\frac{\partial}{\partial \theta_2} \log L(\theta, \mathbf{x})
& \left(\frac{\partial}{\partial \theta_2} \log L(\theta,
\mathbf{x}) \right)^2
\end{bmatrix}.
\]
Remarks
The Fisher information matrix is a
square matrix. Its dimension
is dependent on the dimension of the vector of parameters. For the case
of a k-dimensional parameter vector, the dimension of the corresponding
Fisher information matrix is \(k\times
k\).
The individual cell element in the Fisher information matrix is
expressed in the following
\[
[\mathbb{I}_n(\mathbf{\theta})]_{i,j} = \frac{\partial}{\partial
\theta_i} \log L(\theta, \mathbf{x})\frac{\partial}{\partial \theta_j}
\log L(\theta, \mathbf{x})
\]
The Fisher information matrix is the covariance matrix of the
gradient vector \(\partial \log L(\theta:
\mathbf{x})/\partial \theta\).
The Fisher information at each individual observed data point
\(x_i\) is still a \(k\times k\) square matrix and is similarly
given by
\[
I_0(\theta)= E \begin{bmatrix}
\left(\frac{\partial}{\partial \theta_1} \log L(\theta, x_i)
\right)^2 & \frac{\partial}{\partial \theta_1} \log L(\theta,
x_i)\frac{\partial}{\partial \theta_2} \log L(\theta, x_i) \\
\frac{\partial}{\partial \theta_1} \log L(\theta,
x_i)\frac{\partial}{\partial \theta_2} \log L(\theta, x_i) &
\left(\frac{\partial}{\partial \theta_2} \log L(\theta, x_i) \right)^2
\end{bmatrix}.
\]
- For an IID sample \(\{x_1, x_2, \cdots,
x_n\} \sim f(\mathbf{x}: \theta)\),
\[
I_n(\theta) = nI_0(\theta).
\]
Analogous to the case of single parameter distributions, we also
have the following alternative definition of the Fisher information
matrix for multi-parameter distributions
\[
\mathbb{I}_n(\mathbf{\theta}) = -E\left( \frac{\partial^2}{\partial
\theta \partial \theta^T} \log L(\theta:\mathbf{x})\right).
\]
where
\[
\mathbb{H}_n(\theta, \mathbf{x})=\frac{\partial^2}{\partial \theta
\partial \theta^T} \log L(\theta:\mathbf{x}) =
\begin{bmatrix}
\frac{\partial^2}{\partial \theta_1^2} \log L(\theta, x_i) &
\frac{\partial^2}{\partial \theta_1 \partial \theta_2} \log L(\theta,
x_i) & \cdots & \frac{\partial^2}{\partial \theta_1 \partial
\theta_k} \log L(\theta, x_i) \\
\frac{\partial^2}{\partial \theta_2 \partial \theta_1} \log
L(\theta, x_i)) & \frac{\partial^2}{\partial \theta_2^2} \log
L(\theta, x_i) & \cdots & \frac{\partial^2}{\partial \theta_2
\partial \theta_k} \log L(\theta, x_i) \\
\vdots & \vdots & \vdots \\
\frac{\partial^2}{\partial \theta_k \partial \theta_1} \log
L(\theta, x_i)& \frac{\partial^2}{\partial \theta_k \partial
\theta_2} \log L(\theta, x_i) & \cdots
& \frac{\partial^2}{\partial \theta_k^2 } \log L(\theta, x_i)
\end{bmatrix}_{k\times k}
\]
is the well-known Hessian matrix. Hessian
Matrices are widely used in optimization problems.
Caution: Hessian
Matrix and Jacobian Matrix are sometimes confusing.
The Hessian matrix is the square matrix of
second-order partial derivatives of the objective function to be
optimized.
The Jacobian matrix is the first-order
derivatives of a vector of functions such as \((f_1(\theta), f_2(\theta), \cdots,
f_k(\theta))\) where \(\theta =
(\theta_1, \theta_2, \cdots, \theta_k)\). The Jacobian
matrix associated with the vector of functions is defined
by
\[
J(\theta) = \begin{bmatrix}
\frac{\partial}{\partial \theta_1} f_1(\theta) &
\frac{\partial}{\partial \theta_2} f_1(\theta) & \cdots &
\frac{\partial}{\partial \theta_k} f_1(\theta) \\
\frac{\partial}{\partial \theta_1} f_2(\theta) &
\frac{\partial}{\partial \theta_2} f_2(\theta) & \cdots &
\frac{\partial}{\partial \theta_k} f_2(\theta) \\
\vdots & \vdots & \vdots \\
\frac{\partial}{\partial \theta_1} f_k(\theta) &
\frac{\partial}{\partial \theta_2} f_k(\theta) & \cdots &
\frac{\partial}{\partial \theta_k} f_k(\theta)
\end{bmatrix}_{k\times k}
\]
- When finding the MLE of unknown parameters from the objective
log-likelihood function \(l(\theta)\),
we first calculate gradient functions
\[
\left(\frac{\partial l(\theta)}{\partial \theta_1}, \frac{\partial
l(\theta)}{\partial \theta_2}, \cdots, \frac{\partial
l(\theta)}{\partial \theta_k}\right) \stackrel{\text{def}}{\equiv}
[f_1(\theta), f_2(\theta), \cdots, f_k(\theta)]
\]
\(\hspace{5mm}\) Then the
Hessian Matrix associated with the objective function
\(l(\theta)\) and the Jacobian
Matrix associated with gradient (score) functions
are identical.
Multiple Random
Variables and Random Vectors
We first introduce the concept of covariance and properties
associated with multiple random variables.
Let \(X\) and \(Y\) be two variables, the covariance that
measures the linear relationship between two random variables is defined
by
\[
\text{cov}(X,Y) = E\{[X-E(X)][Y-E(Y)]\}.
\]
Some properties of covariance:
\(\text{cov}(X,Y) =
\text{cov}(Y,X)\).
When \(X = Y\), \(\text{cov}(X,Y) = \text{var}(X)\).
Let \(a\) and \(b\) are scalars,
- \(\text{cov}(aX, Y) = a \times
\text{cov}(X,Y)\);
- \(\text{cov}(aX, bY) = ab \times
\text{cov}(X,Y)\);
- \(\text{cov}(aX + b, Y) = a\times
\text{cov}(X,Y)\)
Let \(Z = aX + bY\), \(E(Z) = E[aX + bY] = aE[X] + bE[Y]\) and
\(\text{var}(Z) = a^2\text{var}(X) = 2ab\cdot
\text{cov}(X,Y) + b^2 \text{var}(Y)\).
(Prove this using the definition of the variance.)
The (linear) correlation coefficient between \(X\) and \(Y\) is given by \[
\rho = \frac{\text{cov}(X, Y)}{\sqrt{\text{var}(X)\text{var}(Y)}}
\]
For a given sample \(\{(x_1, y_1), (x_2,
y_2), \cdots, (x_n, y_n) \}\), the sample correlation coefficient
is given by
\[
r = \frac{\left[\sum_{i=1}^n
(x_i-\bar{x})(y_i-\bar{y})\right]/n}{\sqrt{\frac{\sum_{i=1}^n
(x_i-\bar{x})^2}{n}\frac{\sum_{i=1}^n (y_i-\bar{y})^2}{n}}} =
\frac{\sum_{i=1}^n (x_i-\bar{x})(y_i-\bar{y})}{\sqrt{\sum_{i=1}^n
(x_i-\bar{x})^2\sum_{i=1}^n (y_i-\bar{y})^2}}.
\]
The variance of the linear combination of random variables \(X\) and \(Y\), \(Z = aX +
bY\), involves covariance of \(X\) and \(Y\). In general, we can consider the linear
combination of a sequence of random variables \(\{X_1, X_2, \cdots, X_p \}\), say \(W = \sum_{i=1}^p a_iX_i\), we can calculate
the variance of \(W\) in the
following
\[
\text{var}(W) = \sum_{i=1}^p a_i^2 \text{var}(X_i) + \sum_{i\ne j}
a_ia_j \text{cov}(X_i, X_j)
\]
The above variance of \(W\) is
obtained based on the definition of variance and binomial expansion.
However, we can write the linear combination of the random variance in
the vector form
\[
W = (a_1, a_2, \cdots, a_p) \begin{bmatrix}
X_1 \\
X_2 \\
\vdots \\
X_p
\end{bmatrix}.
\]
Therefore, \(W\) is the dot product
of a scalar vector (coefficient of the linear combination) and a random
vector. This motivates us to study random vectors.
Random Vectors and Properties
We have discussed the distribution of single random variables and the
related characterization. If we have a vector of \(p\) random variables
\[
\mathbf{X} = \begin{bmatrix}
X_1 \\
X_2 \\
\vdots \\
X_p
\end{bmatrix}.
\].
Each random variable has support (i.e., domain) \(\mathbb{R}_i \subseteq \mathbb{R}\) for
\(i = 1, 2, \cdots, p\). Let
\[
\mathbf{x} = \begin{bmatrix}
x_1 \\
x_2 \\
\vdots \\
x_p
\end{bmatrix}.
\].
be the realization (i.e., observed data values) of random variable
\(\mathbb{X}\). This means
\[
\mathbf{x} \in (\mathbb{R}_1 \times \mathbb{R}_2 \times \cdots \times
\mathbb{R}_p)^T.
\]
The mean of the random vector is
\[
E(\mathbf{X}) \stackrel{\text{def}}{\equiv} \begin{bmatrix}
E(X_1) \\
E(X_2) \\
\vdots \\
E(X_p)
\end{bmatrix}
= \begin{bmatrix}
\mu_1 \\
\mu_2 \\
\vdots \\
\mu_p
\end{bmatrix}
.
\]
The variance-covariance matrix is defined by
\[
V[\mathbf{X}] \stackrel{\text{def}}{\equiv}
\begin{bmatrix}
\text{var} (X_1) & \text{cov}(X_1, X_2) & \cdots &
\text{cov}(X_1, X_p) \\
\text{cov} (X_2,X_1) & \text{var}(X_2) & \cdots &
\text{cov}(X_2, X_p) \\
\vdots & \vdots & \vdots & \vdots\\
\text{cov} (X_k,X_1) & \text{cov}(X_p,X_2) & \cdots &
\text{var}(X_p)
\end{bmatrix}_{p\times p}
\]
Some Properties of Random Vectors
A constant vector a (vector of constants) satisfies \(E[a] = a\).
For random vectors \(\mathbf{X}\) and \(\mathbf{Y}\), \(E[\mathbf{X} + \mathbf{Y}] = E[\mathbf{X}] +
E[\mathbf{Y}]\)
Let \(\mathbf{a}\) be a scalar
(column) vector and \(\mathbf{X}\) be a
(column) random vector. \(\mathbf{a}^T\mathbf{X}\) is well defined.
Then \(\text{var}(\mathbf{a}^T\mathbf{X}) =
\mathbf{a}^T\text{cov}(\mathbf{X})\mathbf{a}\).
Example Derive the variance of \(Z = aX + bY\) using the properties of
random vectors. Let \(\mathbf{d} =
(a,b)\)
\[
\text{var}(Z) = \text{var}(\mathbf{d}^T\mathbf{Z}) =
\mathbf{d}^T\text{cov}(\mathbf{Z})\mathbf{d}
\]
\[
= [a,b]\begin{bmatrix}
\text{var}(X) & \text{cov}(X,Y) \\
\text{cov}(Y, X) & \text{var}(Y)
\end{bmatrix}
\begin{bmatrix}
a\\
b
\end{bmatrix}
\]
Expand the above matrix to get the quadratic form
\[
\text{var}(Z) = a^2 \text{var}(X) + 2ab\times \text{cov}(X,Y) + b^2
\text{var}(Y).
\]
Multivariate Normal
Distribution
Recall the density function of univariate random variable \(X\) with mean \(\mu\) and variance \(\sigma^2\) is given by
\[
f(x) = \frac{1}{\sqrt{2\pi}\sigma}e^{-\frac{(x-\mu)^2}{2\sigma^2}}, \ \
\text{ for } \ -\infty < x < \infty.
\]
Example: Suppose \(X\) is the height (in inches) and \(Y\) is the weight (in pounds) of a male
student in a large university. Furthermore suppose that \(X\) and \(Y\) follow normal distribution with
parameters \(\mu_X=69\), \(\mu_Y=155\), \(\sigma_X=2.5\), and \(\sigma_Y=20\). Furthermore, the correlation
coefficient between \(X\) and \(Y\) is \(\rho=0.55\). There may be different
distributions that satisfy the given conditions. However, the given
conditions uniquely determine the bivariate normal distribution that has
the following joint density function
\[
f(x,y)=\frac{1}{2\pi\sigma_x\sigma_y\sqrt{1-\rho^2}}\exp\left\{-\frac{1}{2(1-\rho^2)}
\left[ \left(\frac{x-\mu_x}{\sigma_x} \right)^2 +
\left(\frac{y-\mu_y}{\sigma_y} \right)^2
-\rho\left(\frac{x-\mu_x}{\sigma_x}
\right)\left(\frac{y-\mu_y}{\sigma_y} \right) \right] \right\}.
\]
Obviously, the density for the Bivariate Normal is ugly, and it only
gets worse when we consider higher dimensional joint densities of more
normal distributions. We can write the density in a more compact form
using matrix notation,
Denote
\[
\mathbf{x} = \begin{bmatrix}
x \\
y
\end{bmatrix}, \ \ \ \
\mu = \begin{bmatrix}
\mu_x \\
\mu_y
\end{bmatrix} \ \ \ \
\mathbf{\Sigma} = \begin{bmatrix}
\sigma_x^2 & \rho\sigma_x\sigma_y \\
\rho\sigma_x\sigma_y & \sigma_y^2
\end{bmatrix} \ \ \ \
\]
The matrix form of the bivariate normal distribution is given by
\[
f(\mathbf{x}) = \frac{1}{2\pi}
(\text{det}\mathbf{\Sigma})^{-1/2}\exp\left[-\frac{1}{2}(\mathbf{x}-\mu)^T
\mathbf{\Sigma}^{-1}(\mathbf{x}-\mu)\right].
\]
\(\Sigma\) is the covariance matrix
of \(\mathbf{x}\). The above expression
can be generalized to multivariate normal distribution. The multivariate
normal distribution is uniquely determined if the covariance matrix is
specified.
With the above example, we can
specify the vector and covariance matrix required in the bivariate
normal distribution.
\[
\mu = \begin{bmatrix}
69 \\
155
\end{bmatrix} \ \ \text{ and } \ \
\mathbf{\Sigma} = \begin{bmatrix}
2.5^2 & 0.55\times 2.5 \times 20\\
0.55\times 2.5 \times 200 & 20^2
\end{bmatrix} =
\begin{bmatrix}
6.25 & 27.5\\
27.5 & 400
\end{bmatrix}
\]
\[
\text{det}\mathbf{\Sigma} = 6.25\times 400 - 27.5^2 = 1743.75.
\] and
\[
\mathbf{\Sigma}^{-1} = \frac{1}{6.25\times 400 - 27.5^2}\begin{bmatrix}
400 &
-27.5 \\
-27.5 &
6.25
\end{bmatrix}
= \begin{bmatrix}
0.2293907 & -0.01577061 \\
-0.01577061 & 0.003584229
\end{bmatrix}.
\]
\[
f(\mathbf{x}) = 0.0038\exp \left[-\frac{1}{2}(x-69, y-155)
\begin{bmatrix}
0.2294 & -0.0158 \\
-0.0158 & 0.0036
\end{bmatrix}
\begin{bmatrix}
x-69 \\
y-155
\end{bmatrix}
\right].
\]
Notation of General Multivariate Normal
Distribution
Let
\[
\mathbf{X} = \begin{pmatrix}
X_1 \\
X_2 \\
\vdots \\
X_k
\end{pmatrix}, \ \ \
\mathbf{\mu} = \begin{pmatrix}
\mu_1 \\
\mu_2 \\
\vdots \\
\mu_k
\end{pmatrix}, \ \ \text{ and } \ \
\mathbf{\Sigma} = \begin{pmatrix}
\sigma_1^2 & \sigma_{12} & \sigma_{13} & \cdots &
\sigma_{1k} \\
\sigma_{21} & \sigma_2^2 & \sigma_{23} & \cdots &
\sigma_{2k} \\
\vdots & \vdots & \vdots & \vdots & \vdots \\
\sigma_{k1} & \sigma_{k2} & \sigma_{k3} & \cdots &
\sigma_{kk}
\end{pmatrix}.
\]
We use the following notation to denote the k-dimensional normal
distribution
\[
\mathbf{X} \sim \mathcal{N}_k(\mu, \mathbf{\Sigma}).
\]
Properties of Multivariate Normal
Distributions
Let \(\mathbf{X} = [X_1, X_2, \cdots,
X_k]^T\) and \(\mu =
E[\mathbf{X}]\), and \(\text{cov}(\mathbf{X}) = \mathbf{\Sigma} =
(\sigma_{ij})\). The multivariate normal distribution is given
by
\[
\mathbf{X} \rightarrow_p \mathcal{N}_k(\mu, \mathbf{\Sigma}).
\]
The following are properties of multivariate normal distributions
that will be used in the subsequent note.
All marginal distributions
(distribution of individual component of
multivariate normal) of a multivariate normal distribution
are normal distributions.
All conditional distributions of a multivariate
normal distribution are normal distribution.
All linear combinations of the components of
multivariate normal distribution are also normal
distributions.
Asymptotic Normality
of MLE
Recall the MLE of \(\mathbf{\theta}\) based on IID \(\{x_1, x_2, \cdots, x_n \}
\stackrel{\text{iid}}{\sim} f(x:\theta)\), denoted by \(\hat{\theta}\), is the solution to the
following optimization problem
\[
\hat{\mathbf{\theta}} = \arg\min_{\theta \in \Theta} \log L(\theta:
\mathbf{x})
\]
where \(L(\theta)\) is the
likelihood of \(\theta\) that given
explicitly in the following
\[
L(\theta: \mathbf{x}) = \prod_{i=1}^n f(x_i:\theta).
\]
The Fisher Information of \(\theta\) is given by
\[
\mathbb{I}_n(\theta) = E\left[ \left(\frac{\partial}{\partial \theta}
\log L(\theta:\mathbf{x})\right) \left( \frac{\partial}{\partial \theta}
\log L(\theta:\mathbf{x}) \right)^T\right]
\]
\[
= - E\left[ \frac{\partial^2}{\partial \theta \partial \theta^T} \log
L(\theta:\mathbf{x})\right].
\]
Denote the Fisher Information Matrix based on
individual observed data points by
\[
\mathbb{I}_0(\theta) =- E\left[ \frac{\partial^2}{\partial \theta
\partial \theta^T} \log L(\theta:x)\right] =
\frac{\mathbb{I}_n(\theta)}{n}.
\]
With the above discussions and notations, we have the following
sampling distribution of MLE of \(\theta\).
Theorem: (Asymptotic normality of MLE)
Under some regularity conditions, the MLE of \(\theta\) based on \(\{x_1, x_2, \cdots, x_n
\}\stackrel{\text{iid}}{\sim} f(x:\theta)\) has the following
asymptotic normality
\[
\sqrt{n}(\hat{\theta} - \theta) \stackrel{\text{approx}}{\rightarrow_p}
\mathcal{N}\left[\mathbf{0}, \mathbb{I}_0^{-1}(\theta)\right].
\]
Since \(\theta\) in the covariance
matrix \(\mathbb{I}_0^{-1}\) is
unknown. When making inferences, we use \(\widehat{\mathbb{I}_0(\theta)} =
\mathbb{I}_0(\hat{\theta})\).
Remarks:
\(\sqrt{n}(\hat{\theta} -
\theta)\) is approximately normally distributed when the sample
size is large. The variance of \(\sqrt{n}(\hat{\theta} - \theta)\) is \(\mathbb{I}_0^{-1}(\theta)\) which is
independent of the sample size and is defined based on the individual
random data point.
\(\theta\) is the unknown
parameter and \(\hat{\theta}\) is the
MLE of \(\theta\).
\(\sqrt{n}(\hat{\theta} -
\theta)\) can be considered as a sequence of random variables
(indexed by the sample size \(n\)).
\(\rightarrow_p\) stands for
converges in distribution.
Example: The following data represent active repair
times (in hours) for an airborne communication transceiver.
0.2, 0.3, 0.5, 0.5, 0.5, 0.5, 0.6, 0.6, 0.7, 0.7, 0.7, 0.8, 0.8, 1.0,
1.0, 1.0, 1.0, 1.1, 1.3, 1.5, 1.5, 1.5, 1.5, 2.0, 2.0, 2.2, 2.5, 3.0,
3.0, 3.3, 3.3, 4.0, 4.0, 4.5, 4.7, 5.0, 5.4, 5.4, 7.0, 7.5, 8.8, 9.0,
10.3, 22.0, 24.5.
Assuming the above data set was taken from a Weibull distribution
with density function \(f(x, \alpha, \beta) =
\alpha\beta x^{\beta-1} e^{-\alpha x^\beta}\).
As we derived in the previous note, the log-likelihood of observing
the data is a function of \(\alpha\)
and \(\beta\)
\[
l(\alpha, \beta) = n[\log(\alpha) + \log (\beta)] + (\beta
-1)\sum_{i=1}^n\log (x_i)-\alpha\sum_{i=1}^n x_i^\beta
\]
library(plotly)
# Data set
dat = c(0.2, 0.3, 0.5, 0.5, 0.5, 0.5, 0.6, 0.6, 0.7, 0.7, 0.7, 0.8, 0.8, 1.0, 1.0,
1.0, 1.0, 1.1, 1.3, 1.5, 1.5, 1.5, 1.5, 2.0, 2.0, 2.2, 2.5, 3.0, 3.0, 3.3,
3.3, 4.0, 4.0, 4.5, 4.7, 5.0, 5.4, 5.4, 7.0, 7.5, 8.8, 9.0, 10.3, 22.0, 24.5)
n = length(dat)
x1 = seq(0.1, 0.5, length = 50)
y1 = seq(0.1, 1, length = 50)
## log-likelihood
zfun <- function(x1,y1){
exp(n*log(x1) + n*log(y1) + (y1-1)*sum(log(dat)) - x1*sum(dat^y1))
}
z = outer(x1, y1, zfun)
plot_ly(x = x1, y = y1, z = z) %>% add_surface()
The score equations are given by
\[
\begin{cases}
\frac{\partial l(\alpha, \beta)}{\partial \alpha} = \frac{n}{\alpha} -
\sum_{i=1}^n x_i^\beta= 0 , \\
\frac{\partial l(\alpha, \beta)}{\partial \beta}= \frac{n}{\beta} +
\sum_{i=1}^n \log(x_i) - \alpha \sum_{i=1}^n x_i^\beta \log(x_i)= 0.
\end{cases}
\]
We next write R code to find the MLE and the Hessian matrix (the
negative observed Fisher Information Matrix).
# Data set
x = c(0.2, 0.3, 0.5, 0.5, 0.5, 0.5, 0.6, 0.6, 0.7, 0.7, 0.7, 0.8, 0.8, 1.0, 1.0, 1.0, 1.0,
1.1, 1.3, 1.5, 1.5, 1.5, 1.5, 2.0, 2.0, 2.2, 2.5, 3.0, 3.0, 3.3, 3.3, 4.0, 4.0, 4.5,
4.7, 5.0, 5.4, 5.4, 7.0, 7.5, 8.8, 9.0, 10.3, 22.0, 24.5)
n = length(x)
## log-likelihood
negLogLik = function(A){
a = A[1]
b = A[2]
n*log(a) + n*log(b) + (b-1)*sum(log(x)) - a*sum(x^b)
}
## gradient function
grFun = function(A){
a = A[1]
b = A[2]
ga = n/a - sum(x^b)
gb= n/b +sum(log(x)) -a*sum(x^b*log(x))
c(ga,gb)
}
## calling R function optim()
results = optim(par = c(.5,.5), fn = negLogLik, gr = grFun, method = "BFGS",
control = list(maxit = 20000,fnscale = -1), hessian = TRUE)
MLE = results$par
Counts = results$counts
Convergence = results$convergence
Hessian = results$hessian
I0.inv = -solve(Hessian/n)
out = list(MLE = MLE, Counts = Counts, Convergence = Convergence, Hessian = Hessian, I0.inv = I0.inv)
out
$MLE
[1] 0.3377259 0.8896178
$Counts
function gradient
33 9
$Convergence
[1] 0
$Hessian
[,1] [,2]
[1,] -394.5369 -236.5124
[2,] -236.5124 -250.2269
$I0.inv
[,1] [,2]
[1,] 0.2631775 -0.2487532
[2,] -0.2487532 0.4149563
grFun(c(0.3377259, 0.8896178))
[1] -6.173184e-06 -5.231722e-06
negLogLik0 = function(A){
a = A[1]
b = A[2]
-(n*log(a) + n*log(b) + (b-1)*sum(log(x)) - a*sum(x^b))
}
nlm(negLogLik0, p = c(1,1), hessian=TRUE)
$minimum
[1] 102.3452
$estimate
[1] 0.3377254 0.8896176
$gradient
[1] -5.566392e-05 -4.544631e-05
$hessian
[,1] [,2]
[1,] 394.3012 236.5408
[2,] 236.5408 250.2637
$code
[1] 1
$iterations
[1] 12
Therefore, the sampling distribution of \((\hat{\alpha}, \hat{\beta})\) is given
by
\[
\sqrt{n}\begin{pmatrix}
\hat{\alpha} - \alpha \\
\hat{\beta} - \beta
\end{pmatrix} \rightarrow_p \mathcal{N} \left[
\begin{pmatrix}
0 \\
0
\end{pmatrix},
\begin{pmatrix}
0.2631785 & -0.2487531 \\
-0.2487531 & 0.4149552
\end{pmatrix}
\right]
\]
Remarks
Caution:
The Hessian matrix \(\mathbb{H}\) reported in
optim() is negative observed Fisher information: \(-\widehat{\mathbb{I}_n(\theta)} =
-\mathbb{I}_n(\hat{\theta})\)!
The covariance matrix in the asymptotic normality of MLE requires
\(\mathbb{I}_0(\theta)\). The observed
Fisher information \(\mathbb{\hat{\theta}}\) is equal to the
Hessian matrix, \(\mathbb{H}_n\),
divided by sample size \(n\). That is,
\(\mathbb{I}_0(\hat{\theta}) =
-\mathbb{H(\theta:\mathbf{x})}/n.\)
\(\text{var}[\sqrt{n}(\hat{\alpha})-\alpha] =
n\text{var}(\hat{\alpha}) = 0.2631785\) which implies that \(\text{var}(\hat{\alpha}) = 0.2631785/45 \approx
0.005848411\); \(\text{var}[\sqrt{n}(\hat{\beta})-\beta] =
n\text{var}(\hat{\beta}) = 0.4149552\) which implies that \(\text{var}(\hat{\beta}) = 0.4149552/45 \approx
0.009221227\); and \(\text{cov}(\hat{\alpha}, \hat{\beta}) =
-0.2487531/45 = -0.005527847\).
Let \(\hat{\omega} = c\hat{\alpha} +
d\hat{\beta}\). Then \(\text{var}(\hat{\omega}) = \text{var}[
c\hat{\alpha} + d\hat{\beta}] = c^2\text{var}(\hat{\alpha}) +
d^2\text{var}(\hat{\beta}) + 2cd\text{cov}(\hat{\alpha}, \hat{\beta}) =
0.005848411c^2 + 0.009221227d^2 - 2\times
0.005527847cd\).
Inference of MLE
Three types of inferences will be discussed in this section:
confidence intervals, and significance tests.
Confidence
Intervals
Because MLEs are asymptotically normally distributed, we can use the
same procedure as we used in introductory statistics. Assuming the
confidence level in the subsequent discussion is \(95\%\).
For convenience, let \((\hat{\theta}_1,
\hat{\theta}_2)\) be the MLE of \((\theta_1, \theta_2)\) based on an IID
sample \(\{x_1, x_2, \cdots, x_n \}
\stackrel{\text{i.i.d}}{\sim} f(x, \theta_1, \theta_2)\). The
asymptotic sampling distribution of the MLE is assumed to be
\[
\sqrt{n}
\begin{pmatrix}
\hat{\theta}_1 - \theta_1 \\
\hat{\theta}_2 - \theta_2
\end{pmatrix} \stackrel{\text{approx}}{\rightarrow_p}
\mathcal{N}_2
\left[
\begin{pmatrix}
0 \\
0
\end{pmatrix},
\begin{pmatrix}
\sigma_1^2 & \sigma_{12} \\
\sigma_{12} & \sigma_2^2
\end{pmatrix}
\right],
\] which can be re-expressed in the following form
\[
\begin{pmatrix}
\hat{\theta}_1 \\
\hat{\theta}_2
\end{pmatrix} \stackrel{\text{approx}}{\rightarrow_p}
\mathcal{N}_2
\left[
\begin{pmatrix}
\theta_1 \\
\theta_2
\end{pmatrix},
\frac{1}{n}\begin{pmatrix}
\sigma_1^2 & \sigma_{12} \\
\sigma_{12} & \sigma_2^2
\end{pmatrix}
\right],
\] where
\[
\text{var}(\hat{\theta}_1) = \frac{\sigma_1^2}{n}, \ \
\text{var}(\hat{\theta}_2) = \frac{\sigma_2^2}{n}, \ \ \text{ and } \ \
\text{cov}(\hat{\theta}_1, \hat{\theta}_2) = \frac{\sigma_{12}}{n}.
\]
Example (continued): We can re-express the
asymptotic normality of the MLE in the example in the previous section
as
\[
\begin{pmatrix}
\hat{\alpha} \\
\hat{\beta}
\end{pmatrix} \stackrel{\text{approx}}{\rightarrow_p}
\mathcal{N}_2
\left[
\begin{pmatrix}
\alpha \\
\beta
\end{pmatrix},
\frac{1}{45}\begin{pmatrix}
0.2631785 & -0.2487531 \\
-0.2487531 & 0.4149552
\end{pmatrix}
\right],
\]
this implies
\[
\text{var}(\hat{\alpha}) = \frac{0.2631785}{45} = 0.005848411 \ \
\text{and} \ \ \text{var}(\hat{\beta}) = \frac{0.4149552}{45} =
0.009221227,
\] and
\[
\text{cov}(\hat{\alpha}, \hat{\beta}) = -\frac{0.2487531}{45} =
0.005527847.
\] Recall that the MLE of \((\alpha,
\beta)\) in the example are \(\hat{\alpha} = 0.3377271\) and \(\hat{\beta} = 0.8896159\).
For convenience, we only construct \(95\%\) confidence interval for \(\theta_1\).
- Two-sided confidence interval
\[
\hat{\theta_1} \pm z_{0.975}\frac{\hat{\sigma_1}}{\sqrt{n}}
\]
In the above example, the \(95\%\) confidence interval for \(\alpha\) is
\[
\hat{\alpha}_1 \pm z_{0.975}\sqrt{\frac{\hat{\sigma}_1^2}{45}} =
0.3377271 \pm 1.96 \times \sqrt{\frac{0.2631785}{45}} = (0.1878363,
0.4876179).
\]
- Lower and Upper Confidence Intervals
The \(95\%\) lower and upper
confidence intervals for \(\alpha\) are
given respectively by
\[
\left(-\infty, \hat{\theta}_1 +
z_{0.95}\frac{\hat{\sigma}_1}{\sqrt{n}}\right) \ \ \text{ and } \ \
\left(\hat{\theta}_1 - z_{0.95}\frac{\hat{\sigma}_1}{\sqrt{n}},
\infty\right)
\]
- Linear Confidence Intervals
The linear combination of \(\theta_1\) and \(\theta_2\), denoted by \(\theta_0 = a\theta_1 + b\theta_2\) can be
estimated by \(\hat{\theta}_0 =
a\hat{\theta}_1 + b\hat{\theta}_2\). By the plugin
Principle of MLE, \(\hat{\theta}_0\) is also a normal
distribution. The \(E[\hat{\theta}_0] =
aE[\hat{\theta}_1] + bE[\hat{\theta}_2] = a\mu_1 + b\mu_2\), and
\(\text{var}(\hat{\theta}_0) = a^2\sigma_1^2 +
b^2\sigma_2^2 + 2ab\sigma_{12}\). Then the two-sided \(95\%\) confidence interval is given by
\[
\hat{\theta}_0 \pm z_{0.975}\sqrt{\text{var}(\hat{\theta}_0)}.
\] We can also construct one-sided linear confidence intervals
similarly.
Significance
Tests
Significance tests are common in practice. For example, after we fit
Weibull distribution \(f(x, \alpha, \beta) =
\alpha\beta x^{\beta-1} e^{-\alpha x^\beta}\) to a data set, we
need to assess whether the model was overfitting. If \(\beta = 1\), the Weibull distribution
reduces to a one-parameter exponential distribution. According to the
Principle of Parsimony, we should stay with the
exponential distribution of the data set. Testing the following
hypothesis addresses the above potential overfit/underfit problem.
\[
\mathbb{H}_0: \ \ \beta = 1 \ \ \text{ v.s. } \ \ \mathbb{H}_a: \ \
\beta \ne 1.
\]
The above test is a typical significance test. To perform the above
hypothesis test, we need to know the sampling distribution of the MLE of
\((\alpha, \beta)\) which is assumed to
be
\[
\begin{pmatrix}
\hat{\alpha} \\
\hat{\beta}
\end{pmatrix} \stackrel{\text{approx}}{\rightarrow_p}
\mathcal{N}_2
\left[
\begin{pmatrix}
\alpha \\
\beta
\end{pmatrix},
\begin{pmatrix}
\sigma_1^2/n & \sigma_{12}/n \\
\sigma_{12}/n & \sigma_2^2/n
\end{pmatrix}
\right],
\]
Based on the above asymptotic normality, the test statistic for the
above hypothesis is defined to be
\[
TS = \frac{\hat{\beta}-1}{\hat{\sigma}_2/\sqrt{n}} \sim N(0, 1).
\]
The p-value of the above two-tail test is
\[
\text{p-value} = P[Z > |TS| ], \ \ \text{ where } \ Z \ \text{ is
the standard normal random variable.}
\]
If the p-value is less than a threshold (for example 0.05), the null
hypothesis is rejected. The one-parameter exponential distribution
should be used.
Example (continued):
In the above numerical example assuming Weibull distribution, we want
to see whether an exponential has a better fit. This is equivalent to
testing
\[
\mathbb{H}_0: \ \ \beta = 1 \ \ \text{ v.s. } \ \ \mathbb{H}_a: \ \
\beta \ne 1.
\]
The test statistic is
\[
TS = \frac{0.8896178 - 1}{\sqrt{0.4149563/45}} = -1.149487
\] The p-value is
\[
\text{p-value} = P(Z>|-1.149487|) = 2\times P(Z>-1.149487) \approx
0.2503552.
\]
The null hypothesis is rejected. This implies that
Weibull distribution is more appropriate than exponential.
Remarks:
The above test is based on the assumption of a large
sample.
Since TS is a standard normal distribution. \(TS^2\) is a \(\chi^2_1\) distribution. That is,
\[
W = \left[\frac{\hat{\beta}-1}{\hat{\sigma}_2/\sqrt{n}}\right]^2 \sim
\chi^2_1.
\]
\(W\) is called
Wald statistic. The test is called the Wald
Test.
Example (continued):
\[
W = \left[\frac{\hat{\beta}-1}{\sqrt{\hat{\sigma}_2^2/n}}\right]^2 =
\left[\frac{0.8896178 - 1}{\sqrt{0.4149563/45}}\right]^2 = (-1.149487)^2
= 1.32132.
\]
The p-value based on the above statistic is
\[
\text{p-value} = P(\chi^2_1 > 1.32132) \approx 0.2503553.
\]
Remark: All \(\chi^2\) tests are right-tailed!
Score Test
Consider the null hypothesis
\[
H_0: \ \ \theta = \theta_0.
\] which defines a restricted parameter space.
We also need the restricted MLE before defining the test
statistic. Let
\[
\theta_{\text{rMLE}} = \arg\max_{\theta \in \Theta_R}\log
L(\theta:\mathbf{x}).
\]
We have shown at the beginning of the section that
\[
E\left[ \frac{\partial}{\partial \theta} \log L(\theta:\mathbf{x})
\right] = \mathbf{0},
\]
and
\[
\mathbb{I}_n(\theta) = -E\left[\left(\frac{\partial}{\partial\theta}\log
L(\theta, \mathbf{x})\right)\left(\frac{\partial}{\partial\theta}\log
L(\theta, \mathbf{x})\right)^T \right]
\]
We also showed that
\[
\text{var} \left[\frac{\partial}{\partial \theta} \log
L(\theta:\mathbf{x})\right] = \mathbb{I}_n(\theta)
\]
and
\[
\frac{\partial}{\partial \theta} \log L(\theta:\mathbf{x}) \rightarrow_p
\mathcal{N}_k\left[\mathbf{0}, \mathbb{I}_n(\theta)\right]
\] where \(k = \dim (\Theta) - \dim
(\Theta_R)\).
Theorem: with the above notations and some
regularity conditions, the following asymptotic normality holds.
\[
S_n = \left[\frac{\partial}{\partial\theta}\log L(\theta_{\text{rMLE}},
\mathbf{x})\right]^T
\mathbb{I}_n^{-1}(\theta_{\text{rMLE}})\left[\frac{\partial}{\partial\theta}\log
L(\theta_{\text{rMLE}}, \mathbf{x})\right] \rightarrow_p \chi^2_k,
\]
where \(\theta_{\text{rMLE}}\) is
the restricted MLE under the null hypothesis.
Example (continued): The Weibull example revisited.
We still consider
\[
H_0: \ \ \beta = 1 \ \ \text{vs} \ \ H_a: \beta \ne 1.
\]
Under \(H_0: \ \ \beta = 1\), the
Weibull distribution is reduced to the exponential distribution with
density \(f(x) = \alpha e^{-\alpha
x}\). Therefore, the restricted MLE is \(\theta_{\text{rMLE}} = (\hat{\alpha}, \beta=1) =
(1/\bar{x},1)\).
To define the score test statistic, we need to find the gradient
vector and the Fisher information matrix based on the unrestricted
parameter space.
The log-likelihood function is
\[
l(\alpha, \beta) = n[\log(\alpha) + \log (\beta)] + (\beta
-1)\sum_{i=1}^n\log (x_i)-\alpha\sum_{i=1}^n x_i^\beta
\]
The score functions are given by
\[
\begin{cases}
\frac{\partial l(\alpha, \beta)}{\partial \alpha} = \frac{n}{\alpha} -
\sum_{i=1}^n x_i^\beta, \\
\frac{\partial l(\alpha, \beta)}{\partial \beta}= \frac{n}{\beta} +
\sum_{i=1}^n \log(x_i) - \alpha \sum_{i=1}^n x_i^\beta \log(x_i).
\end{cases}
\]
x= c(0.2, 0.3, 0.5, 0.5, 0.5, 0.5, 0.6, 0.6, 0.7, 0.7, 0.7, 0.8, 0.8, 1.0, 1.0, 1.0, 1.0,
1.1, 1.3, 1.5, 1.5, 1.5, 1.5, 2.0, 2.0, 2.2, 2.5, 3.0, 3.0, 3.3, 3.3, 4.0, 4.0, 4.5,
4.7, 5.0, 5.4, 5.4, 7.0, 7.5, 8.8, 9.0, 10.3, 22.0, 24.5)
n = length(x)
##
lb = n + sum(log(x)) - (1/mean(x))*sum(x*log(x))
lb
[1] -11.12719
The Score vector is
\[
U(\theta_{\text{rMLE}}) = \left[ 0, -11.12719 \right]
\] and
\[
\frac{\partial^2}{\partial \alpha^2}\log L(\alpha:\mathbf{x}) =
-\frac{n}{\alpha^2}, \ \ \text{and} \ \ \frac{\partial^2}{\partial
\alpha \partial \beta}\log L(\alpha:\mathbf{x}) = -\sum_{i=1}^n
x_i^\beta \log(x_i)
\]
\[
\frac{\partial^2}{\partial \beta^2}\log L(\alpha:\mathbf{x}) =
-\frac{n}{\beta^2} -\sum_{i=1}^n x_i^\beta \log(x_i)
\]
## Inverse observed Fisher Information matrix
x= c(0.2, 0.3, 0.5, 0.5, 0.5, 0.5, 0.6, 0.6, 0.7, 0.7, 0.7, 0.8, 0.8, 1.0, 1.0, 1.0, 1.0,
1.1, 1.3, 1.5, 1.5, 1.5, 1.5, 2.0, 2.0, 2.2, 2.5, 3.0, 3.0, 3.3, 3.3, 4.0, 4.0, 4.5,
4.7, 5.0, 5.4, 5.4, 7.0, 7.5, 8.8, 9.0, 10.3, 22.0, 24.5)
n = length(x)
##
laa = -n*mean(x)
lab = -sum(x*log(x))
lbb = -n-sum(x*log(x))
IIn = matrix(c(laa, lab, lab, lbb), nrow=2)
IIn.inv = solve(IIn)
IIn.inv
[,1] [,2]
[1,] 0.009319889 -0.008137795
[2,] -0.008137795 0.004287062
The observed Fisher information matrix based on the restricted MLE is
given by
\[
\mathbb{I}_n^{-1}(\theta_{\text{rMLE}}) =
\begin{bmatrix}
0.009319889 & -0.008137795 \\
-0.008137795 & 0.004287062
\end{bmatrix}
\]
## Score test statistic
Sn=c(0, -11.12719)%*% IIn.inv %*% c( 0, -11.12719)
Sn
[,1]
[1,] 0.5307998
The score test statistic is
\[
S_n = [0, -11.12719]\begin{bmatrix}
0.009319889 & -0.008137795 \\
-0.008137795 & 0.004287062
\end{bmatrix}
\begin{bmatrix}
0 \\
-11.12719
\end{bmatrix} \approx 0.5307998.
\]
Since \(S_n \rightarrow_p
\chi^2_1\). The p-value of the score test is given by
\[
\text{p-value} = P[\chi^2_1 > 0.5307998] = 0.4662708.
\]
The null hypothesis \(H_0: \beta =
1\) is not rejected. This is consistent with the Wald \(\chi^2\) test.
Likelihood Ratio Test
(LRT)
The likelihood ratio (LR) test
The likelihood ratio test is one of the most commonly used in
likelihood-based statistical inferences. It is a test of hypothesis in
which two different maximum likelihood estimates of a parameter are
compared in order to decide whether to reject or not to reject a
restriction on the parameter (such as setting \(\beta = 1\) in the previous Weibull
distribution).
This note focuses on parametric likelihood inferences. The LRT is
used to compare two nested models. The basic setup is outlined in the
following.
In essence, the LRT is based on two MLEs from two parameter spaces:
full parameter space (\(\Theta\)) and restricted
parameter space \(\Theta_{R}\).
Full (Unrestricted) Parameter Space: The
parameter space containing all values that the parameter vector can
take. For example, for normal distribution with density \(N(\mu, \sigma)\), \(\mu \in \mathbb{R}\) and standard deviation
\(\sigma \in \mathbb{R}^+\), then \(\Theta \stackrel{\text{def}}{\equiv}
\mathbb{R}\times \mathbb{R}^+\) is the parameter space of \(\theta = c(\mu, \sigma)\).
Restricted Parameter Space: A subspace of the
unrestricted space. For example, in the 2-parameter Weibull
distribution, the parameter space is \(\Theta
= \mathbb{R}^+\times \mathbb{R}^+\) because both parameters
(\(\alpha, \beta\)) are positive. That
is, \(\Theta\) is spanned by \((\alpha, \beta)\). If we set \(\beta = 1\), \((\alpha, 1)\) spans the restricted
parameter space \(\Theta_R =
\mathbb{R}^+\times \{1\}\).
- Unrestricted and Restricted Maximum Likelihood: The
unrestricted maximum likelihood is based on the unrestricted parameter
space (\(\Theta\)) and the restricted
maximum likelihood is based on the restricted parameter space (\(\Theta_R\)). The unrestricted and
restricted MLEs are given by
\[
\hat{\theta}_{MLE} = \arg\max_{\theta\in \Theta} \log L(\theta:
\mathbf{x})
\]
and
\[
\hat{\theta}_{rMLE} = \arg\max_{\theta\in \Theta_R} \log L(\theta:
\mathbf{x})
\]
With the above notations, we state the following theorem. The proof
is out of the scope of this series of tutorials.
Theorem: Let \(\hat{\theta}_{\text{MLE}}\) and \(\hat{\theta}_{\text{rMLE}}\) be the
unrestricted MLE and restricted MLE estimated based on \(\Theta\) and \(\Theta_R\) respectively. Denote \(\text{df} = \dim(\Theta) -
\dim(\Theta_R)\), then the test statistic for testing the null
hypothesis
\[
H_{\text{0}}: \theta_0 \in \Theta_R
\]
is defined to be
\[
LRT=-2\ln
\frac{L(\hat{\theta}_{rMLE}:\mathbf{x})}{L(\hat{\theta}_{MLE}:\mathbf{x})}
\rightarrow_p\chi^2_{\text{df}.}
\] The p-value of the above likelihood ratio \(\chi^2\) test is determined by
\[
\text{p-value} = P(\chi^2_{\text{df}} > LRT).
\]
Recap of LRT
The likelihood ratio \(\chi^2\) test
involves three technical steps:
Find the MLE of the parameters in the restricted parameter space
(\(\mathbb{\Theta}_R\)) which is
defined based on the null hypothesis \(H_0\).
Find the MLE of the parameters in the unrestricted parameter
space (\(\mathbb{\Theta}\)).
Evaluate the likelihood ratio statistic and find the p-value
based on the resulting \(\chi^2_{\text{df}}\) with \(\text{df} = \text{dim} (\mathbb{\Theta})-
\text{dim} (\mathbb{\Theta}_R)\).
Example (Weibull example revisited): We will follow
the above three technical steps for testing the null hypothesis
\[
H_0: \beta = 1 \ \ \text{ vs } \ \ H_a: \beta \ne 1.
\]
Note that \(H_0\) defines the
restricted space \(\mathbb{\Theta}_R =
\mathbb{R}^+ \times {1}\). We need to find a value from all
possible values of \(\alpha\) given
\(\beta = 1\) that maximizes the
log-likelihood of observing the data.
Step 1: Find the restricted MLE is the MLE of exponential
distribution with density \(f(x, \alpha) =
\alpha e^{-\alpha x}\).
We know the solution to the optimization problem has a closed form
\(\hat{\alpha} = n/\sum_{i=1}^n x_i = 45/163.2
\approx 0.2757353\). That is, restricted MLE \(\theta_{rMLE} = 0.2757353\). The
log-likelihood evaluated at the restricted MLE is given by
\[
\log L(\hat{\theta}_{rMLE}, \mathbf{x}) = n\log(a) - a\sum_{i=1}^{45}x_i
\]
\[
=45\log(0.2757353)-0.2757353\times 163.2 = -102.9741.
\]
The log-likelihood curve and its critical point is given in the
figure below.
# Data set
x = c(0.2, 0.3, 0.5, 0.5, 0.5, 0.5, 0.6, 0.6, 0.7, 0.7, 0.7, 0.8, 0.8, 1.0, 1.0, 1.0, 1.0,
1.1, 1.3, 1.5, 1.5, 1.5, 1.5, 2.0, 2.0, 2.2, 2.5, 3.0, 3.0, 3.3, 3.3, 4.0, 4.0, 4.5,
4.7, 5.0, 5.4, 5.4, 7.0, 7.5, 8.8, 9.0, 10.3, 22.0, 24.5)
n = length(x)
## log-likelihood
negLogLik = function(a){
b = 1
n*log(a) - a*sum(x^b)
}
## gradient function
## We first plot the log-likelihood function
alpha = seq(0.01, 1, length=100)
lglik = negLogLik(alpha)
plot(alpha, lglik, type="l", ylab ="Loglikelihood")
abline(v=0.2757353, col="red")
points(0.2757353, negLogLik(0.2757353), pch=19, col = "red", cex = 1.5)
text(0.5, -150, "(0.2757, -103.0)", col="blue")
arrows(0.2757, negLogLik(0.2757353), 0.5, -145, length = 0.05, angle = 30,
code = 2)
Step 2: log-likelihood evaluated at unrestricted MLE.
The unrestricted MLE has found in the previous example \(\hat{\theta}_{MLE} =(\hat{\alpha}, \hat{\beta})
\approx (0.3377271, 0.8896159)\). The log-likelihood evaluated at
\((\hat{\alpha}, \hat{\beta}) \approx
(0.3377271, 0.8896159)\) is
\[
\log L(\hat{\theta}: \mathbf{x}) = n\log(\alpha) + n\log(\beta) +
(\beta-1)\sum_{i=1}^n\log(x_i) - \alpha\sum_{i=1}^n(x_i^\beta)
\]
# Data set
x = c(0.2, 0.3, 0.5, 0.5, 0.5, 0.5, 0.6, 0.6, 0.7, 0.7, 0.7, 0.8, 0.8, 1.0, 1.0, 1.0, 1.0,
1.1, 1.3, 1.5, 1.5, 1.5, 1.5, 2.0, 2.0, 2.2, 2.5, 3.0, 3.0, 3.3, 3.3, 4.0, 4.0, 4.5,
4.7, 5.0, 5.4, 5.4, 7.0, 7.5, 8.8, 9.0, 10.3, 22.0, 24.5)
n = length(x)
## log-likelihood
negLogLik = function(A){
a = A[1]
b = A[2]
n*log(a) + n*log(b) + (b-1)*sum(log(x)) - a*sum(x^b)
}
# 0.3377259 0.8896178
A = c(0.3377259, 0.8896178)
lglik = negLogLik(A)
lglik
[1] -102.3452
Step 3: Evaluating the LRT and finding the p-value.
\[
LRT = -2\log \frac{L(\hat{\theta}_{rMLE}:
\mathbf{x})}{L(\hat{\theta}_{MLE}: \mathbf{x})}=-2\left[\log
L(\hat{\theta}_{rMLE}: \mathbf{x}) - \log L(\hat{\theta}_{MLE}:
\mathbf{x}) \right] \rightarrow_p \chi^2_1.
\]
The value of the above test statistic is
\[
LRT = -2[ -102.9741- (-102.3452)] = 1.2578.
\] The p-value of the LRT test is calculated in the following
\[
\text{p-value} = P[\chi^2_1>1.2578] = 0.7379321.
\]
This implies that there is an overfit issue if we choose the
two-parameter Weibull distribution to fit the given data. The
one-parameter exponential is a better choice for this application.
LS0tDQp0aXRsZTogIjUuIExpa2VsaWhvb2QtYmFzZWQgSW5mZXJlbmNlcyINCmRhdGU6ICI2LzMwLzIwMjQiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdG9jX2NvbGxhcHNlZDogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgc21vb3RoX3Njcm9sbDogeWVzDQogICAgdGhlbWU6IGx1bWVuDQogIHBkZl9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KZWRpdG9yX29wdGlvbnM6DQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KDQoNCg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCg0KLyogVGFibGUgb2YgY29udGVudCAtIG5hdmlnYXRpb24gKi8NCmRpdiNUT0MgbGkgew0KICAgIGxpc3Qtc3R5bGU6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLWNvbG9yOmxpZ2h0Z3JheTsNCiAgICBiYWNrZ3JvdW5kLWltYWdlOm5vbmU7DQogICAgYmFja2dyb3VuZC1yZXBlYXQ6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOjA7DQogICAgZm9udC1mYW1pbHk6IEFyaWFsLCBIZWx2ZXRpY2EsIHNhbnMtc2VyaWY7DQogICAgY29sb3I6ICM3ODBjMGM7DQp9DQoNCg0KLyogVGl0bGUgZm9udHMgKi8NCmgxLnRpdGxlIHsNCiAgZm9udC1zaXplOiAyNHB4Ow0KICBjb2xvcjogZGFya2JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC1mYW1pbHk6IEFyaWFsLCBIZWx2ZXRpY2EsIHNhbnMtc2VyaWY7DQogIGZvbnQtdmFyaWFudC1jYXBzOiBub3JtYWw7DQp9DQpoNC5hdXRob3IgeyANCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LWZhbWlseTogQXJpYWwsIEhlbHZldGljYSwgc2Fucy1zZXJpZjsNCiAgY29sb3I6IG5hdnk7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmg0LmRhdGUgeyANCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LWZhbWlseTogQXJpYWwsIEhlbHZldGljYSwgc2Fucy1zZXJpZjsNCiAgY29sb3I6IGRhcmtibHVlOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCi8qIFNlY3Rpb24gaGVhZGVycyAqLw0KaDEgew0KICAgIGZvbnQtc2l6ZTogMjJweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMiB7DQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmgzIHsgDQogICAgZm9udC1zaXplOiAxNXB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmg0IHsNCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KLyogRGVjb3JhdGlvbiBvZiBoeXBlcmxpbmtzICAqLw0KDQovKiB1bnZpc2l0ZWQgbGluayAqLw0KYTpsaW5rIHsNCiAgY29sb3I6IGdyZWVuOw0KfQ0KDQovKiB2aXNpdGVkIGxpbmsgKi8NCmE6dmlzaXRlZCB7DQogIGNvbG9yOiBwdXJwbGU7DQp9DQoNCi8qIG1vdXNlIG92ZXIgbGluayAqLw0KYTpob3ZlciB7DQogIGNvbG9yOiByZWQ7DQp9DQoNCi8qIHNlbGVjdGVkIGxpbmsgKi8NCmE6YWN0aXZlIHsNCiAgY29sb3I6IHllbGxvdzsNCn0NCjwvc3R5bGU+DQoNCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQpvcHRpb25zKHJlcG9zID0gbGlzdChDUkFOPSJodHRwOi8vY3Jhbi5yc3R1ZGlvLmNvbS8iKSkNCiMgY29kZSBjaHVuayBzcGVjaWZpZXMgd2hldGhlciB0aGUgUiBjb2RlLCB3YXJuaW5ncywgYW5kIG91dHB1dCANCiMgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IGZpbGVzLg0KaWYgKCFyZXF1aXJlKCJrbml0ciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpDQogICBsaWJyYXJ5KGtuaXRyKQ0KfQ0KDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSwgICANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBUUlVFLCAgIA0KICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICBjb21tZW50ID0gTkEpDQpgYGANCg0KXA0KDQoNCg0KIyBMaWtlbGlob29kIFJldmlldw0KDQpMZXQgJFx0aGV0YSQgYmUgYW4gdW5rbm93biBwYXJhbWV0ZXIgb3IgYSB2ZWN0b3Igb2YgdW5rbm93biBwYXJhbWV0ZXJzLiBBc3N1bWUgdGhhdCAkXHtYXzEsIFhfMiwgXGNkb3RzLCBYX24gXH0kIGlzIGEgc2V0IG9mIElJRCByYW5kb20gdmFyaWFibGVzIHdpdGggZGlzdHJpYnV0aW9uICRGKHg7IFx0aGV0YSkkLiBXaGVuIHRoZSBkaXN0cmlidXRpb24gaXMgZGlzY3JldGUsIHRoZSBwcm9iYWJpbGl0eSBtYXNzIGZ1bmN0aW9uIChQTUYpIGlzIHVzZWQgaW4gdGhlIGxpa2VsaWhvb2QgZnVuY3Rpb24uIElmIHRoZSBkaXN0cmlidXRpb24gaXMgY29udGludW91cywgdGhlIHByb2JhYmlsaXR5IGRpc3RyaWJ1dGlvbiBkZW5zaXR5IGZ1bmN0aW9uIChQREYpIGlzIHVzZWQgaW4gdGhlIGxpa2VsaWhvb2QgZnVuY3Rpb24uDQoNCldlIG9ubHkgZm9jdXMgb24gY29udGludW91cyBkaXN0cmlidXRpb25zIGluIHRoaXMgc2VyaWVzIG9mIHJlc2VhcmNoIHR1dG9yaWFscy4gSW4gdGhlIHJlc3Qgb2YgdGhpcyBub3RlLCB3ZSBhc3N1bWUgJFx7WF8xLCBYXzIsIFxjZG90cywgWF9uIFx9JCBpcyBhIHNldCBvZiBJSUQgY29udGludW91cyByYW5kb20gdmFyaWFibGVzIHdpdGggZGVuc2l0eSBmdW5jdGlvbiAkZih4OyBcdGhldGEpJC4gKipEaXNjcmV0ZSBkaXN0cmlidXRpb25zIHN1Y2ggYXMgYmlub21pYWwgYW5kIFBvc3NvbiBkaXN0cmlidXRpb25zIGFyZSB1c2VkIG9jY2FzaW9uYWxseSB0byBleHBsYWluIHNvbWUgY29uY2VwdHMuKiogDQoNCg0KUmVjYWxsIHRoYXQgdGhlIGxpa2VsaWhvb2Qgb2Ygb2JzZXJ2aW5nIGFuIElJRCByYW5kb20gc2FtcGxlICRce3hfMSwgeF8yLCBcY2RvdHMsIHhfbiBcfSQgZnJvbSB0aGUgZGlzdHJpYnV0aW9uIHdpdGggZGVuc2l0eSBmdW5jdGlvbiAkZih4O1x0aGV0YSkkIGlzIGdpdmVuIGJ5DQoNCiQkDQpMKFx0aGV0YXwgXG1hdGhiZnt4fSkgPSBccHJvZF97aSA9IDF9Xm4gZih4X2k6IFx0aGV0YSkNCiQkDQoNClRoZSBNTEUgb2YgJFx0aGV0YSQsIGRlbm90ZWQgYnkgJFxoYXR7XHRoZXRhfSQgaXMgdGUgc29sdXRpb24gdG8gdGhlIG9wdGltaXphdGlvbiBwcm9ibGVtDQoNCiQkDQpcaGF0e1x0aGV0YX0gPSBcYXJnIFxtYXhfe1x0aGV0YSBcaW4gXE9tZWdhfSBMKFx0aGV0YTogXG1hdGhiZnt4fSkuDQokJA0KDQpTaW5jZSB0aGUgbG9nYXJpdGhtIG9mIHRoZSBsaWtlbGlob29kIGlzIGVhc2llciB0byBoYW5kbGUgaW4gbWF0aGVtYXRpY3MsIHdlIGRlZmluZSB0aGUgYWJvdmUgb3B0aW1pemF0aW9uIHByb2JsZW0gdXNpbmcgdGhlIGxvZy1saWtlbGlob29kLCB0aGF0IGlzDQoNCiQkDQpcaGF0e1x0aGV0YX0gPSBcYXJnXG1heF97XHRoZXRhIFxpbiBcT21lZ2F9IGwoXHRoZXRhOiBcbWF0aGJme3h9KSwNCiQkDQoNCndoZXJlICRsKFx0aGV0YTogXG1hdGhiZnt4fSkgPSBcbG9nIFtMKFx0aGV0YTogXG1hdGhiZnt4fSldJC4NCg0KVGhlIG1ldGhvZCBvZiBtb21lbnQgKE1NKSBhbmQgdGhlIG1heGltdW0gbGlrZWxpaG9vZCBlc3RpbWF0aW9uIChNTEUpIHByb3ZpZGUgYSBzaW5nbGUgZXN0aW1hdGVkIHZhbHVlIGZyb20gYSByYW5kb20gc2FtcGxlIHRvIGFwcHJveGltYXRlIHRoZSB1bmtub3duIHBhcmFtZXRlci4gVGhpcyBlc3RpbWF0aW9uIGlzIGNhbGxlZCAqKnBvaW50IGVzdGltYXRpb24qKi4gVGhpcyBub3RlIHdpbGwgZm9jdXMgb24gaW5mZXJlbmNlcyBiYXNlZCBvbiBNTEUuIA0KDQoNCiMjIFNvbWUgQmFzaWMgQ29uY2VwdHMNCg0KV2UgYnJpZWZseSByZXZpZXcgc29tZSBvZiB0aGUgY29uY2VwdHMgaW50cm9kdWNlZCBpbiBhbiBlYXJsaWVyIG5vdGUuDQoNCioqUGFyYW1ldGVyIGFuZCBTdGF0aXN0aWMqKjogQSBwYXJhbWV0ZXIgaXMgYSBudW1lcmljYWwgY2hhcmFjdGVyaXN0aWMgb2YgYSBwb3B1bGF0aW9uLiBBIHN0YXRpc3RpYyBpcyBhIG51bWVyaWNhbCB2YWx1ZSBjYWxjdWxhdGVkIGZyb20gYSBzYW1wbGUgdGFrZW4gZnJvbSB0aGUgcG9wdWxhdGlvbi4NCg0KKipFc3RpbWF0aW9uLCBFc3RpbWF0b3IsIGFuZCBFc3RpbWF0ZSoqOiBBbiBlc3RpbWF0aW9uIGlzIGEgbWV0aG9kLiBBbiBlc3RpbWF0b3IgaXMgYSBmb3JtdWxhIG9yIGZ1bmN0aW9uIGRlZmluZWQgYmFzZWQgb24gYSBkYXRhIHNldC4gQW4gZXN0aW1hdGUgaXMgYSB2YWx1ZSBjYWxjdWxhdGVkIHVzaW5nIHRoZSBmb3JtdWxhIChpLmUuLCBlc3RpbWF0b3IpIGZyb20gdGhlIGRhdGEgc2V0Lg0KDQoqKlBvaW50IEVzdGltYXRlKio6IGEgcG9pbnQgZXN0aW1hdGUgaXMgYSBzaW5nbGUgdmFsdWUgdXNlZCB0byBlc3RpbWF0ZSB0aGUgcG9wdWxhdGlvbiBwYXJhbWV0ZXIuIEl0IGlzIGEgcmFuZG9tIG51bWJlciBiZWNhdXNlIHRoZSBzYW1wbGUgaXMgcmFuZG9tLg0KDQoqKkludGVydmFsIGVzdGltYXRlKio6IGFuIGludGVydmFsIGVzdGltYXRlIGlzIGEgcmFuZ2UgKGludGVydmFsKSBvZiB2YWx1ZXMgdGhhdCBjb250YWlucyB0aGUgdHJ1ZSB2YWx1ZSBvZiB0aGUgdW5rbm93biBwYXJhbWV0ZXIuIA0KDQoNCioqUmVtYXJrKiogLSBUaGUgcG9pbnQgZXN0aW1hdGUgaXMgb25seSBhIGRlc2NyaXB0aXZlIHN0YXRpc3RpYyBiYXNlZCBvbiB0aGUgc2FtcGxlLCBub3QgdGhlIHBvcHVsYXRpb24uIEZvciBleGFtcGxlLCB3aGVuIGNvbnNpZGVyaW5nIHRoZSBhdmVyYWdlIHN0YXJ0aW5nIHNhbGFyaWVzIG9mIHJlY2VudCBzdGF0aXN0aWNzIGdyYWR1YXRlcyBhdCBhIHVuaXZlcnNpdHksIHdlIHRha2UgYSByYW5kb20gc2FtcGxlIG9mIHN0dWRlbnRzIGFuZCBjYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugc2FsYXJ5LCBzYXkgXCQ1NSwwMDAuIFdlIGNhbiBub3Qgc2F5IHRoZSBhdmVyYWdlIHN0YXJ0aW5nIHNhbGFyeSBvZiBhbGwgc3RhdGlzdGljcyBncmFkdWF0ZXMgYXQgdGhlIHVuaXZlcnNpdHkgaXMgXCQ1NSwwMDAuIEEgYmV0dGVyIHdheSB0byBkZXNjcmliZSB0aGUgc3RhcnRpbmcgc2FsYXJ5IG9mIHRoZSBwb3B1bGF0aW9uIG9mIHN0YXRpc3RpY3MgZ3JhZHVhdGVzIGlzIHRoYXQgdGhlIHN0YXJ0aW5nIHNhbGFyeSBpcyAqKmFyb3VuZCBcJDU1LDAwMCoqIC0gVGhpcyBpcyBhIHJhbmdlISBUaGF0IGlzLCAqd2UgbmVlZCBhbiBpbnRlcnZhbCBlc3RpbWF0ZSB0byBnZW5lcmFsaXplIHRoZSBpbmZvcm1hdGlvbiBmcm9tIHRoZSBzYW1wbGUgdG8gdGhlIHBvcHVsYXRpb24gLSBjb25maWRlbmNlIGludGVydmFsIG1ldGhvZCEqDQoNCg0KIyBHb29kbmVzcyBNZWFzdXJlcyBvZiBQb2ludCBFc3RpbWF0ZQ0KDQpTZXZlcmFsIG1lYXN1cmVzIGFyZSBjb21tb25seSB1c2VkIHRvIGFzc2VzcyB0aGUgZ29vZG5lc3Mgb2YgYSBwb2ludCBlc3RpbWF0ZS4gQmVmb3JlIGludHJvZHVjaW5nIHRoZXNlIG1lYXN1cmVzLCBwbGVhc2Uga2VlcCBpbiBtaW5kIHRoYXQgYW4gZXN0aW1hdGUgZnJvbSBhIHJhbmRvbSBzYW1wbGUgaXMgYWxzbyByYW5kb20uIFRoaXMgbWVhbnMgdGhhdCBhIHBvaW50IGVzdGltYXRlIGhhcyBhIGRpc3RyaWJ1dGlvbi4gV2Ugd2lsbCBkaXNjdXNzIHRoZSBwcm9iYWJpbGl0eSBkaXN0cmlidXRpb24gaW4gYSBzdWJzZXF1ZW50IHNlY3Rpb24uIEZvciBub3csIHdlIG9ubHkgYXNzdW1lIGEgZGlzdHJpYnV0aW9uIGFzc29jaWF0ZWQgd2l0aCB0aGUgcG9pbnQgZXN0aW1hdGUgc28gdGhhdCB3ZSBjYW4gZGVmaW5lIHRoZXNlIG1lYXN1cmVzIHJpZ29yb3VzbHkgdXNpbmcgdGhlIGRlZmluaXRpb24gb2Ygc3RhdGlzdGljYWwgZXhwZWN0YXRpb24uDQoNCkFzc3VtZSB0aGF0ICRcaGF0e1x0aGV0YX0kIGlzIGEgcG9pbnQgZXN0aW1hdGUgb2YgJFx0aGV0YSQgYmFzZWQgb24gYW4gZXN0aW1hdGlvbiBtZXRob2QuIFRoZSBtZWFzdXJlcyBvZiBnb29kbmVzcyBvZiBwb2ludCBlc3RpbWF0ZSBhcmUgYmFzZWQgb24gZXN0aW1hdGlvbiBlcnJvciB3aGljaCBpcyBkZWZpbmVkIHRvIGJlICRcdGV4dHtlcnJvcn0oXGhhdHtcdGhldGF9KSA9IFxoYXR7XHRoZXRhfS0gXHRoZXRhJA0KDQoNCg0KKipCaWFzKio6IHRoZSBiaWFzIG9mIHBvaW50IGVzdGltYXRlICRcaGF0e1x0aGV0YX0kIGlzIGRlZmluZWQgdG8gYmUgJFx0ZXh0e2JpYXN9IChcaGF0e1x0aGV0YX0pID0gRShcaGF0e1x0aGV0YX0gLSBcdGhldGEpID0gRShcaGF0e1x0aGV0YX0pIC0gXHRoZXRhJC4gDQoNClRoZSBiaWFzIG9mIGEgcG9pbnQgZXN0aW1hdGUgY291bGQgYmUgcG9zaXRpdmUsIG5lZ2F0aXZlLCBvciB6ZXJvLiBXaGVuIHRoZSBiaWFzIGlzIHplcm8sICRFKFxoYXR7XHRoZXRhfSkgPSBcdGhldGEkLCB0aGUgY29ycmVzcG9uZGluZyBwb2ludCBlc3RpbWF0ZSBpcyBjYWxsZWQgKip1bmJpYXNlZCBwb2ludCBlc3RpbWF0ZSoqLiBUaGUgKip1bmJpYXNlZG5lc3MqKiBpcyBhIGdvb2QgZmVhdHVyZSBmb3IgYSBwb2ludCBlc3RpbWF0ZS4gIA0KDQoNCioqTWVhbiBTcXVhcmUgRXJyb3IgKE1TRSkqKjogVGhlIE1TRSBvZiBwb2ludCBlc3RpbWF0ZSAkXGhhdHtcdGhldGF9JCBpcyBkZWZpbmVkIHRvIGJlICRcdGV4dHtNU0V9IChcaGF0e1x0aGV0YX0pID0gRVsoXGhhdHtcdGhldGF9LVx0aGV0YSleMl0kLiANCg0KTVNFIGNhbGN1bGF0ZXMgdGhlIGF2ZXJhZ2Ugb2Ygc3F1YXJlZCBlcnJvci4gSXQgaXMgYSBsZWdpdGltYXRlIG1lYXN1cmUgb2YgdGhlIGdvb2RuZXNzIG9mIGEgcG9pbnQgZXN0aW1hdGUuICoqVGhlIHNtYWxsZXIgdGhlIE1TRSwgdGhlIGJldHRlciB0aGUgcG9pbnQgZXN0aW1hdGUuKioNCg0KDQoqKlJlbGF0aW9uc2hpcCBhbW9uZyBCaWFzLCBNU0UsIGFuZCBWYXJpYW5jZSoqOiAkXHRleHR7TVNFfShcaGF0e1x0aGV0YX0pID0gXHRleHR7dmFyfShcaGF0e1x0aGV0YX0pICtbXHRleHR7Ymlhc30gKFxoYXR7XHRoZXRhfSldXjIkDQoNClRoZSBkZXJpdmF0aW9uIG9mIHRoZSBhYm92ZSByZWxhdGlvbnNoaXAgaXMgc3RyYWlnaHRmb3J3YXJkIGJ5IG5vdGluZyB0aGF0ICQoXGhhdHtcdGhldGF9IC0gXHRoZXRhKV4yID0gXHsgWyhcaGF0e1x0aGV0YX0gLSBFKFxoYXR7XHRoZXRhfSldICsgW0UoXGhhdHtcdGhldGF9KS1cdGhldGFdXH1eMi4kLiBFeHBhbmRpbmcgdGhpcyBiaW5vbWlhbCB3aXRoIHNvbWUgYWxnZWJyYWljIGNsZWFuLXVwLCB5b3Ugd2lsbCBzZWUgdGhlIHJlbGF0aW9uc2hpcC4NCg0KDQoqKkFic29sdXRlIEVzdGltYXRpb24gRXJyb3IqKiBpcyBkZWZpbmVkIHRvIGJlICRcZXBzaWxvbiA9IHxcaGF0e1x0aGV0YX0gLSBcdGhldGF8JC4NCg0KDQpXZSBjYW4gbm90IGV2YWx1YXRlIHRoZSBhYm92ZSBnb29kbmVzcyBtZWFzdXJlcyB1bmxlc3MgdGhlIHRydWUgdmFsdWUgb2YgdGhlIHBvcHVsYXRpb24gcGFyYW1ldGVyIGlzIGF2YWlsYWJsZS4gKlRoaXMgaXMgYSBkaWxlbW1hOiB3ZSB0cnkgdG8gbWVhc3VyZSB0aGUgZ29vZG5lc3Mgb2YgdGhlIHBvaW50IGVzdGltYXRlIG9mIGFuIHVua25vd24gcGFyYW1ldGVyLCBidXQgY2FsY3VsYXRpbmcgdGhlc2UgbWVhc3VyZXMgcmVxdWlyZXMgdGhlIHRydWUgdmFsdWUgb2YgdGhlIHVua25vd24gcGFyYW1ldGVyLioNCg0KSW4gZmFjdCwgd2UgdXNlIG1lYXN1cmVzIGluIGRpZmZlcmVudCB3YXlzOg0KDQoxLiBJbiBzaW11bGF0aW9uIHN0dWRpZXMsIHdlIGFzc3VtZSB0aGUgdHJ1ZSB2YWx1ZSBvZiB0aGUgcG9wdWxhdGlvbiBwYXJhbWV0ZXIgYW5kIGdlbmVyYXRlIHJhbmRvbSBzYW1wbGVzLA0KDQoyLiBJZiBwcmlvciBpbmZvcm1hdGlvbiBvbiB0aGUgcG9wdWxhdGlvbiBwYXJhbWV0ZXIgaXMgYXZhaWxhYmxlLCB3ZSBjYW4gYXBwcm94aW1hdGUgdGhlc2UgbWVhc3VyZXMgYmFzZWQgb24gYSByYW5kb20gc2FtcGxlLg0KDQozLiBXZSBjYW4gdXNlIHRoZXNlIG1lYXN1cmVzIHRvIGRlcml2ZSBvdGhlciBpbmZlcmVudGlhbCBwcm9jZWR1cmVzIHN1Y2ggYXMgY29uZmlkZW5jZSBpbnRlcnZhbHMuDQoNCg0KDQojIEludGVydmFsIEVzdGltYXRlcw0KDQpPbmUgaXNzdWUgd2l0aCBhIHBvaW50IGVzdGltYXRlIGlzIHRoYXQgaXQgaGFzIGluZm9ybWF0aW9uIGFib3V0IGFjY3VyYWN5IGFuZCBwcmVjaXNpb24uIFdoZW4gd2Ugc2F5IHRoZSB2YWx1ZSBvZiB0aGUgcG9wdWxhdGlvbiBwYXJhbWV0ZXIgaXMgY2xvc2UgdG8gdGhlIHNhbXBsZSBzdGF0aXN0aWNzLCBidXQgd2UgZG9u4oCZdCBrbm93IGhvdyBjbG9zZSBpdCBpcywgYW5kIGhvdyBjbG9zZSBpcyBjb25zaWRlcmVkIGFzICpjbG9zZSouIFRoaXMgc2VjdGlvbiBpbnRyb2R1Y2VzIHRoZSBnZW5lcmFsIGZyYW1ld29yayB0byBkZXJpdmUgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIGEgcG9wdWxhdGlvbiBwYXJhbWV0ZXIgJFx0aGV0YSQgYmFzZWQgb24gaXRzIHBvaW50IGVzdGltYXRlICRcaGF0e1x0aGV0YX0kICoqd2l0aCB0aGUgYXNzdW1wdGlvbiB0aGF0ICRcaGF0e1x0aGV0YX0kIGhhcyBhIGtub3duIGRlbnNpdHkgJGYoXGhhdHtcdGhldGF9KSQuKioNCg0KDQpXZSBjb25zaWRlciBpbXBvc2luZyBhIGJvdW5kIHRvIHRoZSBhYnNvbHV0aW9uIGVzdGltYXRpb24gZXJyb3IgJFxlcHNpbG9uID0gfFxoYXR7XHRoZXRhfSAtIFx0aGV0YXwgPCBiJCwgd2UgY2FuIHRoZW4gY2FsY3VsYXRlIHRoZSBwcm9iYWJpbGl0eSANCg0KJCQNClAofFxoYXR7XHRoZXRhfSAtIFx0aGV0YXwgPCBiKSA9IFAoXHRoZXRhIC0gYiA8XGhhdHtcdGhldGF9IDxcdGhldGEgKyBiICkgPSBcaW50X3tcdGhldGEtYn1ee1x0aGV0YSArYn0gZihcaGF0e1x0aGV0YX0pIGRcaGF0e1x0aGV0YX0gPSBwXzANCiQkDQoNClRoZSBhYm92ZSAkcF8wJCBpcyB0aGUgZGVyaXZlZCBwcm9iYWJpbGl0eSB0aGF0IHRoZSBhYnNvbHV0ZSBlc3RpbWF0aW9uIGVycm9yIGlzIGJvdW5kZWQgYnkgZ2l2ZW4gJGIkIHdpdGggJFx0aGV0YSQgYmVpbmcga25vd24uIFVuZGVyIHRoZXNlIGFzc3VtcHRpb25zLCB0aGUgaW5lcXVhbGl0eSAkXHRoZXRhIC0gYiA8XGhhdHtcdGhldGF9IDxcdGhldGEgKyBiJCBpbiB0aGUgbWlkZGxlIG9mIHRoZSBhYm92ZSBlcXVhdGlvbiB0ZWxscyBob3cgdGhlIHBvaW50IGVzdGltYXRlIGlzIGNsb3NlIHRvIHRoZSBwYXJhbWV0ZXIgd2l0aCBwcm9iYWJpbGl0eSAkcF8wJC4gKipUaGF0IGlzLCB3aXRoIGtub3duICRcdGhldGEsIGIkLCBhbmQgJGZfe1xoYXR7XHRoZXRhfX0oXGNkb3QpJCwgd2UgY2FuIGNhbGN1bGF0ZSB0aGUgcHJvYmFiaWxpdHkgdGhhdCAkXGhhdHtcdGhldGF9JCBmYWxscyBpbnRvIGludGVydmFsICQoXHRoZXRhIC0gYiwgXHRoZXRhICtiKSQqKi4gDQoNCg0KTmV4dCwgd2UgbG9vayBhdCB0aGUgYWJvdmUgZXF1YXRpb24gdW5kZXIgZGlmZmVyZW50IGFzc3VtcHRpb25zOiBhc3N1bWUgd2UgY2hvb3NlIHRoZSB2YWx1ZSBvZiAkcF8wJCwgc2F5ICRwXzAgPSAwLjk1ID0gOTVcJSQuICRcaGF0e1x0aGV0YX0kIGlzIGNhbGN1bGF0ZWQgZnJvbSBhIHJhbmRvbSBzYW1wbGUgYW5kICRiJCBpcyBhIGtub3duIGVycm9yIGJvdW5kLiBOb3RlIHRoYXQgdGhlIGFib3ZlIGVxdWF0aW9uIGNhbiByZS1leHByZXNzZWQgaW50byB0aGUgZm9sbG93aW5nIGZvcm0NCg0KJCQNClAofFxoYXR7XHRoZXRhfSAtIFx0aGV0YXwgPCBiKSA9IFAoXGhhdHtcdGhldGF9IC0gYiA8XHRoZXRhIDxcaGF0e1x0aGV0YX0gKyBiICk9IHBfMC4NCiQkDQoNClRoZSBhYm92ZSBlcXVhdGlvbiBzYXlzIHRoYXQgdGhlIHJhbmRvbSBpbnRlcnZhbCAkKFxoYXR7XHRoZXRhfSAtIGIsIFxoYXR7XHRoZXRhfSArIGIgKSQgaGFzICQxMDBwXzBcJSQgY2hhbmNlIHRvIGluY2x1ZGUgdGhlIHRydWUgdmFsdWUgb2YgdGhlIHBhcmFtZXRlciAtIFRoaXMgaXMgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgd2l0aCBjb25maWRlbmNlIGxldmVsICQxMDBwXzBcJSA9IDk1XCUkIHdpdGggdGhlIGNob2ljZSBvZiAkcF8wID0gMC45NSQuIA0KDQoqKk9uZSBwaWVjZSBvZiBpbmZvcm1hdGlvbiB0aGF0IG5lZWRzIHRvIGJlIGFkZHJlc3NlZCBpcyBob3cgdG8gZ2V0ICRiJCBpbiB0aGUgYWJvdmUgZGlzY3Vzc2lvbi4qKg0KDQpJbiBvbmUtc2FtcGxlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIG9mIHRoZSBwb3B1bGF0aW9uIG1lYW4sIHdlIHVzZSBlaXRoZXIgdGhlIGNlbnRyYWwgbGltaXQgdGhlb3JlbSBvZiB0aGUgc3Ryb25nIGFzc3VtcHRpb24gb2Ygbm9ybWFsaXR5IG9mIHRoZSBwb3B1bGF0aW9uLCB0aGUgc2FtcGxlIG1lYW4gYXMgdGhlIHBvaW50IGVzdGltYXRlIG9mIHRoZSBwb3B1bGF0aW9uIG1lYW4gJFxtdSQgaGFzIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiwgdGhlbiBiIGlzIHRoZSBtYXJnaW4gb2YgZXJyb3IgKGkuZS4sIGFic29sdXRpb24gZXJyb3IgYm91bmQgb2YgcG9pbnQgZXN0aW1hdGlvbikgdGhhdCBoYXMgdGhlIGZvbGxvd2luZyBmb3JtDQoNCiQkDQpiID0gWl97MS1cYWxwaGEvMn0gXGZyYWN7c317XHNxcnR7bn19DQokJA0KDQp3aGVyZSAkXGFscGhhID0gMSAtIFx0ZXh0e2dpdmVuIGNvbmZpZGVuY2UgbGV2ZWx9JCB3aGljaCBpcyBjYWxsZWQgdGhlIHNpZ25pZmljYW5jZSBsZXZlbCBpbiB0ZXN0aW5nIGh5cG90aGVzZXMuICRaX3sxLVxhbHBoYS8yfSQgaXMgdGhlIHF1YW50aWxlIG9mIHRoZSBkaXN0cmlidXRpb24gb2YgcG9pbnQgZXN0aW1hdGUgJFxoYXR7XG11fSA9IFxiYXJ7WH0kIHdoaWNoIGlzIG5vcm1hbCBpbiB0aGUgb25lIHNhbXBsZSBjb25maWRlbmNlIG9mIHBvcHVsYXRpb24gbWVhbi4gDQoNCg0KVGhlcmVmb3JlLCB0aGUgY3JpdGljYWwgaW5mb3JtYXRpb24gcmVxdWlyZWQgaW4gZGVyaXZpbmcgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgb2YgYSBwb3B1bGF0aW9uIHBhcmFtZXRlciBpcyB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBwb2ludCBlc3RpbWF0ZSBvZiB0aGUgcGFyYW1ldGVyLiBJdCBpcyBjdXN0b21hcmlseSBjYWxsZWQgdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiB0aGUgcG9pbnQgZXN0aW1hdGUuDQoNCg0KIyBTYW1wbGluZyBEaXN0cmlidXRpb24gb2YgTUxFDQoNClJlY2FsbCB0aGUgY2VudHJhbCBsaW1pdCB0aGVvcmVtIGNvbmNlcm5pbmcgdGhlIGRpc3RyaWJ1dGlvbiBvZiBzYW1wbGUgbWVhbnMgd2UgaW50cm9kdWNlZCBpbiB0aGUgZWxlbWVudGFyeSBzdGF0aXN0aWNzOg0KDQoqKkNlbnRyYWwgTGltaXQgVGhlb3JlbSoqIA0KDQoqQXNzdW1lIHRoYXQgYSByYW5kb20gc2FtcGxlICRce3hfMSwgeF8yLCBcY2RvdHMsIHhfbiBcfSQgaXMgdGFrZW4gZnJvbSBhIHBvcHVsYXRpb24gd2l0aCBtZWFuICRcbXUkIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gJFxzaWdtYSQuIERlZmluZSAkXGJhcntYfSA9IFxzdW1fe2kgPTF9Xm4geF9pIC8gbiQgdG8gYmUgdGhlIHBvaW50IGVzdGltYXRlIG9mIHBvcHVsYXRpb24gbWVhbiAkXG11JC4gSWYgdGhlIHNhbXBsZSBpcyBsYXJnZSwgJFxiYXJ7WH0gXHNpbSBOKFxtdSwgXHNpZ21hL1xzcXJ0e259KSQqDQoNCioqUmVtYXJrKio6IFRoZSBjZW50cmFsIGxpbWl0IHRoZW9yZW0gKENMVCkgKipkb2VzIG5vdCBhc3N1bWUqKiBhIHNwZWNpZmljIGRpc3RyaWJ1dGlvbiBvZiB0aGUgcG9wdWxhdGlvbiBidXQgdW5rbm93biBtZWFuICRcbXUkIGFuZCB2YXJpYW5jZSAkXHNpZ21hXjIkLiBUaGUgb25seSB2YWd1ZSBjb25kaXRpb24gaXMgdGhhdCB0aGUgc2FtcGxlIHNpemUgaXMgbGFyZ2UuICoqQW55IHJlc3VsdHMgZGVyaXZlZCBmcm9tIHRoZSBDTFQgYXJlIGNhbGxlZCBsYXJnZSBzYW1wbGUgKGFzeW1wdG90aWMpIHJlc3VsdHMqKi4NCg0KT25lIG9mIHRoZSBvYmplY3RpdmVzIG9mIHRoaXMgbm90ZSBpcyB0byBkZXZlbG9wIGFzeW1wdG90aWMgcmVzdWx0cyBmb3IgdGhlIE1MRSB0aGF0IGFyZSBzaW1pbGFyIHRvIHRoZSBhYm92ZSBDTFQgc28gdGhhdCB3ZSBjYW4gbWFrZSBzdGF0aXN0aWNhbCBpbmZlcmVuY2VzIHN1Y2ggYXMgY29uc3RydWN0aW5nIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGFuZCB0ZXN0aW5nIGh5cG90aGVzZXMuIEluIHRoZSBuZXh0IGZldyBzZWN0aW9ucywgd2UgaW50cm9kdWNlIHRoZSBidWlsZGluZyBibG9ja3MgdG8gYmUgdXNlZCBpbiB0aGUgTUxFLWJhc2VkIGluZmVyZW5jZXMuDQoNCg0KIyMgQmFzaWMgU2V0LXVwIGFuZCBOb3RhdGlvbnMNCg0KTGV0ICRce3hfMSwgeF8yLCBcY2RvdHMsIHhfbiBcfSBcc3RhY2tyZWx7XHRleHR7aS5pLmR9fXtcc2ltfSBmX1x0aGV0YSh4KSQsICRcdGhldGEgPSAoXHRoZXRhXzEsIFx0aGV0YV8yLCBcY2RvdHMsIFx0aGV0YV9rKSQgaXMgYSB2ZWN0b3Igb2YgJGskIHBhcmFtZXRlcnMgKGNvdWxkIGJlIGEgc2luZ2xlIHBhcmFtZXRlciB3aGVuICRrID0gMSQpLiBUaGUgbGlrZWxpaG9vZCBvZiBvYnNlcnZpbmcgdGhlIGRhdGEgaXMgZ2l2ZW4gYnkNCg0KJCQNCkwoXHRoZXRhKSA9IFxwcm9kX3tpPTF9Xm4gZl9cdGhldGEoeF9pKQ0KJCQNCg0KXG5vaW5kZW50IHdpdGggY29ycmVzcG9uZGluZyBsb2ctbGlrZWxpaG9vZCBmdW5jdGlvbiBpbiB0aGUgZm9sbG93aW5nDQoNCiQkDQpsKFx0aGV0YSkgPSBcc3VtX3tpPTF9Xm4gXGxvZyBmX1x0aGV0YSAoeF9pKS4NCiQkDQoNCg0KIyMjIEdyYWRpZW50IFZlY3RvciBhbmQgU2NvcmUgRXF1YXRpb25zDQoNClRoZSBzeXN0ZW0gb2Ygc2NvcmUgZXF1YXRpb25zIGlzIGdpdmVuIGJ5DQoNCiQkDQpcYmVnaW57Y2FzZXN9IA0KXGZyYWN7XHBhcnRpYWwgbChcdGhldGEpfXtccGFydGlhbCBcdGhldGFfMX0gPSAgMCAsICAgIFxcIA0KXGZyYWN7XHBhcnRpYWwgbChcdGhldGEpfXtccGFydGlhbCBcdGhldGFfMn0gPSAwLCAgICAgIFxcDQpcY2RvdHMgXGNkb3RzIFxjZG90cyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFwNClxmcmFje1xwYXJ0aWFsIGwoXHRoZXRhKX17XHBhcnRpYWwgXHRoZXRhX2t9ID0gMC4gDQpcZW5ke2Nhc2VzfSANCiQkDQpUaGUgYWJvdmUgc3lzdGVtIGNhbiBiZSB3cml0dGVuIGluIHRoZSBmb2xsb3dpbmcgZm9ybQ0KDQokJA0KXGZyYWN7XHBhcnRpYWwgbChcdGhldGEpfXtccGFydGlhbCBcdGhldGF9ID0gXG1hdGhiZnswfSBcIFwgXHRleHR7IG9yIH0gXCBcIFxuYWJsYV9cdGhldGEgbChcdGhldGEpID0gXG1hdGhiZnswfQ0KJCQNCg0KVGhlIG1hdGhlbWF0aWNhbCBub3RhdGlvbiAkXG5hYmxhJCAocmVhZCAqLyduYS5ibGEvKikgaXMgYSBkaWZmZXJlbnRpYWwgb3BlcmF0b3IuIEl0IGlzIGNvbW1vbmx5IHVzZWQgaW4gQ2FsY3VsdXMuDQoNClRoZSBncmFkaWVudCB2ZWN0b3Igb2YgJGwoXHRoZXRhKSQgaXMgZGVmaW5lZCB0byBiZQ0KDQokJA0KXG5hYmxhX1x0aGV0YSBsKFx0aGV0YSkgPSBcbGVmdCggXGZyYWN7XHBhcnRpYWwgbChcdGhldGEpfXtccGFydGlhbCBcdGhldGFfMX0sIFxmcmFje1xwYXJ0aWFsIGwoXHRoZXRhKX17XHBhcnRpYWwgXHRoZXRhXzJ9LCBcY2RvdHMgLCBcZnJhY3tccGFydGlhbCBsKFx0aGV0YSl9e1xwYXJ0aWFsIFx0aGV0YV9rfVxyaWdodCkNCiQkDQoNCg0KIyMgRXhwZWN0ZWQgVmFsdWUgb2YgU2NvcmUgRnVuY3Rpb25zDQoNClRvIGRlcml2ZSB0aGUgYXN5bXB0b3RpYyBub3JtYWxpdHkgb2YgdGhlIE1MRSwgd2UgbmVlZCB0byB1c2UgdGhlIGZvbGxvd2luZyByZXN1bHQgZnJvbSBhZHZhbmNlZCByZWFsIGFuYWx5c2lzOiB0aGUgb3JkZXIgb2YgZGlmZmVyZW50aWF0aW9uIGFuZCBpbnRlZ3JhdGlvbiBpcyBleGNoYW5nZWFibGUuIFRoZSBwcm9vZiBvZiBnZW5lcmFsIHJlc3VsdHMgcmVxdWlyZXMgbW9yZSBhZHZhbmNlZCBtYXRoZW1hdGljYWwgdG9vbHMgaW4gdGhlIGFic3RyYWN0IG1lYXN1cmUgdGhlb3J5ICh0byBiZSBjb3ZlcmVkIGluIHRoZSBkb2N0b3JhbC1sZXZlbCByZWFsIGFuYWx5c2lzIGNvdXJzZSkuDQoNCioqTGVtbWEgMSoqOiBTdXBwb3NlIHRoYXQgJGYoeCxcdGhldGEpJCBpcyBkaWZmZXJlbnRpYWJsZSBpbiAkXHRoZXRhJCBhbmQgdGhlcmUgZXhpc3RzIGEgZnVuY3Rpb24gJGcoeCxcdGhldGEpJCBzdWNoIHRoYXQNCg0KMS4gJFxiaWd8IFxmcmFje1xwYXJ0aWFsIGYoeCwgXHZhcnRoZXRhKX17XHBhcnRpYWwgXHZhcnRoZXRhfSBcYmlnfCBcbGUgZyh4LCBcdGhldGEpJCBmb3IgYWxsICR4JCBhbmQgJFx0aGV0YSQgc3VjaCB0aGF0ICR8XHZhcnRoZXRhIC0gXHRoZXRhfFxsZSBcZGVsdGFfMCQ7DQoNCjIuICRcaW50X3stXGluZnR5fV5caW5mdHkgZyh4LCBcdGhldGEpIGR4IDwgXGluZnR5JCBmb3IgYWxsICRcdGhldGEkLg0KDQpUaGVuDQoNCiQkXGZyYWN7ZH17ZFx0aGV0YX0gXGludF97LVxpbmZ0eX1eXGluZnR5IGYoeCxcdGhldGEpIGR4ID0gXGludF97LVxpbmZ0eX1eXGluZnR5IFxmcmFje1xwYXJ0aWFsIGYoeCwgXHRoZXRhKX17XHBhcnRpYWwgXHRoZXRhfSBkeC4NCiQkDQoNCg0KV2Ugd2lsbCBub3QgcHJvdmUgdGhlIGxlbW1hIGluIHRoaXMgbm90ZS4gRm9yIHRoZSBsaWtlbGlob29kIGZ1bmN0aW9uLCB0aGUgcmVndWxhcml0eSBjb25kaXRpb25zIGFyZSBzYXRpc2ZpZWQuIFNvIHdlIGNhbiB1c2UgdGhlIGxlbW1hIGluIHN0YXRpc3RpY2FsIGluZmVyZW5jZS4NCg0KKipGYWN0KiouIFRoZSBleHBlY3RlZCB2YWx1ZSBvZiB0aGUgc2NvcmUgZnVuY3Rpb24gaXMgZXF1YWwgdG8gemVyby4NCg0KKipQcm9vZioqOiBXZSB3aWxsIHVzZSB0aGUgZGVmaW5pdGlvbiBvZiBleHBlY3RhdGlvbiBhbmQgdGhlIGFib3ZlIGxlbW1hIGluIHRoZSBmb2xsb3dpbmcgcHJvb2YuIFdpdGhvdXQgbG9zcyBvZiBnZW5lcmFsaXR5LCB3ZSBjb25zaWRlciB0aGUgbG9nLWxpa2VsaWhvb2Qgb2Ygb2JzZXJ2aW5nIGEgc2luZ2xlIGRhdGEgcG9pbnQgJGYoeDpcdGhldGEpJCBhbmQgYXNzdW1lICRcdGhldGEkIHRvIGJlIGEgdW5pdmFyaWF0ZSBwYXJhbWV0ZXIuDQoNCiQkDQpFXGxlZnRbIFxmcmFje1xwYXJ0aWFsIFxsb2cgZih4LCBcdGhldGEpfXtccGFydGlhbCBcdGhldGF9IFxyaWdodF0gXHN0YWNrcmVse1x0ZXh0e2RlZn19ez19IFxpbnRfey1caW5mdHl9XlxpbmZ0eSBcZnJhY3tccGFydGlhbCBcbG9nIGYoeCwgXHRoZXRhKX17XHBhcnRpYWwgXHRoZXRhfSBmKHgsIFx0aGV0YSkgZHggDQokJA0KDQokJA0KPSBcaW50X3stXGluZnR5fV5caW5mdHkgXGxlZnRbXGZyYWN7XHBhcnRpYWwgZih4LCBcdGhldGEpL1xwYXJ0aWFsIFx0aGV0YX17Zih4LFx0aGV0YSl9XHJpZ2h0XSBmKHgsIFx0aGV0YSkgZHggPSBcaW50X3stXGluZnR5fV5caW5mdHkgXGZyYWN7XHBhcnRpYWwgZih4LCBcdGhldGEpfXtccGFydGlhbCBcdGhldGF9IGR4DQokJA0KDQokJA0KXHN0YWNrcmVse1x0ZXh0e3N3aXRjaH19ez19IFxmcmFje1xwYXJ0aWFsfXtccGFydGlhbCBcdGhldGF9IFxpbnRfey1caW5mdHl9XlxpbmZ0eSBmKHgsIFx0aGV0YSkgZHggPSBcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXHRoZXRhfSAoMSkgPSAwLg0KJCQNCg0KDQoqKlJlbWFya3MqKiBMZW1tYSAxIGludHJvZHVjZWQgaW4gdGhpcyBzdWJzZWN0aW9uIGlzIHJlbGF0ZWQgdG8gc2V2ZXJhbCAqYmlnKiB0aGVvcmVtcyBpbiBtYXRoZW1hdGljcyAoYWR2YW5jZWQgY2FsY3VsdXMgYW5kIHJlYWwgYW5hbHlzaXMpLg0KDQoxLiBUaGUgdHdvIGNvbmRpdGlvbnMgaW4gTGVtbWEgMSBhcmUgYWxzbyBjYWxsZWQgKnJlZ3VsYXJpdHkgY29uZGl0aW9ucyouIE1hbnkgc3RhdGlzdGljYWwgdGhlb3JlbXMgKG9yIHByb2NlZHVyZXMpIHJlcXVpcmUgc29tZSByZWd1bGFyaXR5IGNvbmRpdGlvbnMgbmVlZGVkIGluIG1hdGhlbWF0aWNhbCBwcm9vZnMgYW5kIGRlcml2YXRpb25zLiBNYWtlIHN1cmUgdGhhdCB0aGUgcmVndWxhcml0eSBjb25kaXRpb25zIGFyZSBzYXRpc2ZpZWQgaW4gcHJhY3RpY2FsIGFwcGxpY2F0aW9ucy4NCg0KMi4gSWYgdGhlIGludGVncmFsIGlzIGRlZmluaXRlIHdpdGggc2NhbGFyIGludGVncmFsIGxpbWl0cywgdGhlbiBhYm92ZSBMZW1tYSAxIGlzIGEgc3BlY2lhbCBjYXNlIG9mICoqTGVpYm5peiBSdWxlKiogaW4gQ2FsY3VsdXMuIA0KDQozLiBNb3JlIGdlbmVyYWwgZm9ybXMgb2YgdGhlIGFib3ZlIExlbW1hIDEgYXJlIGludHJvZHVjZWQgaW4gdGhlIHJlYWwgYW5hbHlzaXMgdGV4dGJvb2tzIHVuZGVyIHZhcmlvdXMgY29udmVyZ2VuY2UgdGhlb3JlbXMgc3VjaCBhcyAqKkxlYmVzZ3VlIERvbWluYW50IENvbnZlcmdlbmNlIChpLmUuLCBib3VuZGVkIGNvbnZlcmdlbmNlIHRoZW9yZW0pIGFuZCBNb25vdG9uZSBjb252ZXJnZW5jZSB0aGVvcmVtKiouDQoNCjQuIFNpbmNlIHRoZSBkZXJpdmF0aXZlIGlzIHRoZSBsaW1pdCBvZiB0aGUgcmF0ZSBvZiBjaGFuZ2UgKGluc3RhbnRhbmVvdXMgcmF0ZSksIHRoZXJlIGlzIGFsc28gYSBydWxlIG9mIGV4Y2hhbmdlIGluIHRoZSBvcmRlciBvZiBpbnRlZ3JhbCBhbmQgbGltaXQuDQoNCjUuIFRoZSBpbnRlZ3JhbCBpcyBhbHNvIHZpZXdlZCBhcyBhbiAqaW5maW5pdGUgc3VtKiwgdGhlcmUgaXMgYWxzbyBhIHJ1bGUgb2YgZXhjaGFuZ2Ugb2YgdGhlIG9yZGVyIG9mIHN1bW1hdGlvbiBhbmQgZGVyaXZhdGl2ZSAob3Igc3VtbWF0aW9uIGFuZCBsaW1pdCkuDQoNCjYuIDxmb250IGNvbG9yID0gInJlZCI+KipcY29sb3J7cmVkfVRoZXNlIHR5cGVzIG9mIGV4Y2hhbmdlIG9yZGVyIG9wZXJhdGlvbnMgYXJlIGZyZXF1ZW50bHkgdXNlZCBpbiBzdGF0aXN0aWNzIGRlcml2aW5nIGFzeW1wdG90aWMgc3RhdGlzdGljYWwgcmVzdWx0cy4qKjwvZm9udD4NCg0KDQpcDQoNClRvIGNvbmNsdWRlIHRoaXMgc3Vic2VjdGlvbiwgd2UgdXNlIHRoZSBzYW1lIGlkZWEgaW4gTGVtbWEgMSB0byBkZXJpdmUgdGhlIGZvbGxvd2luZyBMZW1tYSBjb25jZXJuaW5nIHRoZSBzZWNvbmQtb3JkZXIgZGVyaXZhdGl2ZSBvZiB0aGUgbG9nLWxpa2VsaWhvb2QgZnVuY3Rpb24uIExlbW1hIDIgbGlua3MgdGhlIHR3byBkZWZpbml0aW9ucyBvZiB0aGUgKipGaXNoZXIgSW5mb3JtYXRpb24qKiB0byBiZSBpbnRyb2R1Y2VkIGluIHRoZSBuZXh0IHN1YnNlY3Rpb24uDQoNCioqTGVtbWEgMioqOiBVbmRlciBzb21lIHNpbWlsYXIgcmVndWxhcml0eSBjb25kaXRpb25zIChhcyBzdGF0ZWQgaW4gTGVtbWEgMSksIHdlIGhhdmUgDQoNCiQkDQpFXGxlZnRbIFxmcmFje1xmcmFje1xwYXJ0aWFsXjJ9e1xwYXJ0aWFsIFx0aGV0YV4yfWYoeCxcdGhldGEpfXtmKHgsXHRoZXRhKX1ccmlnaHRdID0gMC4NCiQkDQoNCg0KKipQcm9vZioqOiAgVXNpbmcgdGhlIGRlZmluaXRpb24gb2YgZXhwZWN0YXRpb24gYW5kIHRoZSBleGNoYW5nZSBvZiB0aGUgb3JkZXIgb2YgdGhlIGRlcml2YXRpdmUgYW5kIHRoZSBpbnRlZ3JhbCwgd2UgaGF2ZSANCg0KJCQNCkVcbGVmdFsgXGZyYWN7XGZyYWN7XHBhcnRpYWxeMn17XHBhcnRpYWwgXHRoZXRhXjJ9Zih4LFx0aGV0YSl9e2YoeCxcdGhldGEpfVxyaWdodF0gPSBcaW50IFxsZWZ0WyBcZnJhY3tcZnJhY3tccGFydGlhbF4yfXtccGFydGlhbCBcdGhldGFeMn1mKHgsXHRoZXRhKX17Zih4LFx0aGV0YSl9XHJpZ2h0XSBmKHgsXHRoZXRhKWR4DQokJA0KDQokJA0KPSBcaW50IFxmcmFje1xwYXJ0aWFsXjJ9e1xwYXJ0aWFsIFx0aGV0YV4yfWYoeCxcdGhldGEpIGR4IFxzdGFja3JlbHtcdGV4dHtzd2l0Y2h9fXs9fSAgXGZyYWN7XHBhcnRpYWxeMn17XHBhcnRpYWwgXHRoZXRhXjJ9IFxpbnQgZih4LFx0aGV0YSkgZHggPSBcZnJhY3tccGFydGlhbF4yfXtccGFydGlhbCBcdGhldGFeMn0gKDEpID0gMC4NCiQkDQoNClwNCg0KDQojIyBGaXNoZXIgSW5mb3JtYXRpb24gTWF0cml4DQoNClRoZSBpbmZvcm1hdGlvbiBvbiB0aGUgKip2YXJpYW5jZSBhbmQgY292YXJpYW5jZSBvZiB0aGUgTUxFKiogaXMgY29udGFpbmVkIGluIHRoZSBGaXNoZXIgaW5mb3JtYXRpb24gbWF0cml4LiBJdCBtdXN0IGJlIGV4cGxpY2l0bHkgc3BlY2lmaWVkIHdoZW4gbWFraW5nIGluZmVyZW5jZXMgYWJvdXQgdGhlIE1MRSBvZiBtb2RlbCBwYXJhbWV0ZXJzLiBUbyBiZXR0ZXIgdW5kZXJzdGFuZCB0aGUgY29uY2VwdCwgd2Ugc3RhcnQgd2l0aCB0aGUgY2FzZSB3aXRoIHNpbmdsZS1wYXJhbWV0ZXIgbW9kZWxzLg0KDQoNCiMjIyBGaXNoZXIgSW5mb3JtYXRpb24gTnVtYmVyDQoNCkFzc3VtZSB0aGF0ICRcdGhldGEkIGlzIGEgdW5pdmFyaWF0ZSBwYXJhbWV0ZXIgb2YgdGhlIHBvcHVsYXRpb24gd2l0aCBkZW5zaXR5ICRmKHgsXHRoZXRhKSQuIExldCAkXHt4XzEsIHhfMiwgXGNkb3RzLCB4X24gXH0gXHNpbSBmKHgsIFx0aGV0YSkkIGJlIGFuIElJRCBzYW1wbGUuIFdlIHVzZSB2ZWN0b3IgJFxtYXRoYmZ7eH0kIHRvIGRlbm90ZSB0aGUgc2V0IG9mIHJhbmRvbSBzYW1wbGVzLiBUaGUgbG9nLWxpa2VsaWhvb2Qgb2Ygb2JzZXJ2aW5nIHRoZSBkYXRhIGlzIGEgZnVuY3Rpb24gb2YgJFx0aGV0YSQgdGhhdCBoYXMgdGhlIGZvbGxvd2luZyBmb3JtDQoNCiQkDQpsKFx0aGV0YTpcbWF0aGJme3h9KSA9IFxsb2cgTChcdGhldGE6IFxtYXRoYmZ7eH0pID0gXHN1bV97aT0xfV5uIFxsb2cgZih4X2ksIFx0aGV0YSkuDQokJA0KDQoNClRoZSAqKkZpc2hlciBJbmZvcm1hdGlvbiBOdW1iZXIqKiBiYXNlZCBvbiBhIHJhbmRvbSBzYW1wbGUgd2l0aCBzaXplICRuJCBpcyBkZWZpbmVkIHRvIGJlIG9mIHRoZSBmb2xsb3dpbmcgZm9ybQ0KDQokJA0KSV9uKFx0aGV0YSkgXHN0YWNrcmVse1x0ZXh0e2RlZn19ez19IEVfe1xtYXRoYmZ7eH19XGxlZnRbIFxsZWZ0KFxmcmFje1xwYXJ0aWFsfXtccGFydGlhbCBcdGhldGF9IFxsb2cgTChcbWF0aGJme3h9LCBcdGhldGEpIFxyaWdodCleMlxyaWdodF0uDQokJA0KDQpMZW1tYSAxIGluIHRoZSBwcmV2aW91cyBzdWJzZWN0aW9uIHNheXMgdGhhdA0KDQokJA0KRV9YXGxlZnRbIFxmcmFje1xwYXJ0aWFsfXtccGFydGlhbCBcdGhldGF9IGYoWF9pLCBcdGhldGEpXHJpZ2h0XSA9IDAgXCBcIFx0ZXh0e2Zvcn0gXCBcIGkgPSAxLCAyLCBcY2RvdHMsIG4uDQokJA0KDQpUaGVyZWZvcmUsDQoNCiQkDQpcbGVmdFx7RV97XG1hdGhiZnt4fX1cbGVmdFsgXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFx0aGV0YX0gXHN1bV97aT0xfV5uIFxsb2cgZih4X2ksIFx0aGV0YSlccmlnaHRdIFxyaWdodFx9XjIgPVxsZWZ0XHsgRV97XG1hdGhiZnt4fX1cbGVmdFsgXGZyYWN7XHBhcnRpYWwgfXtccGFydGlhbCBcdGhldGF9IFxsb2cgTChcdGhldGE6IFxtYXRoYmZ7eH0pXHJpZ2h0XSBccmlnaHRcfV4yID0gMA0KJCQNCg0KVXNpbmcgdGhlIGZvcm11bGEgJFx0ZXh0e1Zhcn0oWCkgPSBFKFheMikgLSBbRShYKV1eMiQgZm9yIGFsbCByYW5kb20gdmFyaWFibGUgJFgkLCB3ZSBoYXZlDQoNCiQkDQpJX24oXHRoZXRhKSBcc3RhY2tyZWx7XHRleHR7ZGVmfX17PX0gRV97XG1hdGhiZnt4fX1cbGVmdFsgXGxlZnQoXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFx0aGV0YX0gXGxvZyBMKCBcdGhldGE6IFxtYXRoYmZ7eH0pIFxyaWdodCleMlxyaWdodF0gLSBcbGVmdFx7RV97XG1hdGhiZnt4fX1cbGVmdFsgXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFx0aGV0YX0gIFxsb2cgTChcdGhldGE6IFxtYXRoYmZ7eH0pXHJpZ2h0XSBccmlnaHRcfV4yID0gXHRleHR7VmFyfV97XG1hdGhiZnt4fX1cbGVmdFtcbG9nIEwoXHRoZXRhOiBcbWF0aGJme3h9KVxyaWdodF0uDQokJA0KDQpUaGlzIG1lYW5zIHRoYXQgKip0aGUgRmlzaGVyIEluZm9ybWF0aW9uICRJX24oXHRoZXRhKSQgaXMgdGhlIHZhcmlhbmNlIG9mIHRoZSBzY29yZSBmdW5jdGlvbioqLg0KDQoNCg0KTmV4dCwgd2UgcHJlc2VudCBhbiBhbHRlcm5hdGl2ZSBkZWZpbml0aW9uIG9mIHRoZSBGaXNoZXIgSW5mb3JtYXRpb24uIE5vdGUgdGhhdA0KDQokJA0KXGZyYWN7XHBhcnRpYWxeMn17XHBhcnRpYWwgXHRoZXRhXjJ9XGxlZnRbIFxsb2cgTChcdGhldGE6IFxtYXRoYmZ7eH0pIFxyaWdodF0gPSBcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXHRoZXRhfSBcbGVmdFx7IFxmcmFje1xwYXJ0aWFsIH17XHBhcnRpYWwgXHRoZXRhfSBcbGVmdFsgXGxvZyBMKCBcdGhldGE6IFxtYXRoYmZ7eH0pXHJpZ2h0XVxyaWdodFx9ID1cZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXHRoZXRhfSBcbGVmdFx7IFxsZWZ0WyBcZnJhY3tccGFydGlhbCBMKFx0aGV0YTogXG1hdGhiZnt4fSkvXHBhcnRpYWwgXHRoZXRhfXtMKFx0aGV0YTogXG1hdGhiZnt4fSl9XHJpZ2h0XVxyaWdodFx9DQokJA0KVXNpbmcgdGhlIG11bHRpcGxpY2F0aXZlIHJ1bGUgb2YgZGVyaXZhdGl2ZSwgd2UgaGF2ZQ0KDQokJA0KPSBcZnJhY3tMKFx0aGV0YTpcbWF0aGJme3h9KVxmcmFje1xwYXJ0aWFsXjJ9e1xwYXJ0aWFsXHRoZXRhXjJ9TChcdGhldGE6XG1hdGhiZnt4fSkgLSBcbGVmdFtcZnJhY3tccGFydGlhbH17XHBhcnRpYWxcdGhldGF9TChcdGhldGE6XG1hdGhiZnt4fSlccmlnaHRdXjJ9e0xeMihcdGhldGE6IFxtYXRoYmZ7eH0pfQ0KJCQNCg0KJCQNCj1cZnJhY3tcZnJhY3tccGFydGlhbF4yfXtccGFydGlhbFx0aGV0YV4yfUwoXHRoZXRhOlxtYXRoYmZ7eH0pIH17TChcdGhldGE6IFxtYXRoYmZ7eH0pfSAtIFxsZWZ0W1xmcmFje1xmcmFje1xwYXJ0aWFsfXtccGFydGlhbFx0aGV0YX1MKFx0aGV0YTpcbWF0aGJme3h9KSB9e0woXHRoZXRhOiBcbWF0aGJme3h9KX1ccmlnaHRdXjIuDQokJA0KDQoNCkZyb20gTGVtbWEgMiwgdGhlIGZpcnN0IHRlcm0gb2YgdGhlIGFib3ZlIGVxdWF0aW9uIGlzIHplcm8uIFRoZXJlZm9yZSwNCg0KJCQNClxmcmFje1xwYXJ0aWFsXjJ9e1xwYXJ0aWFsIFx0aGV0YV4yfVxsZWZ0WyBcbG9nIEwoXHRoZXRhOiBcbWF0aGJme3h9KSBccmlnaHRdID0gLSBcbGVmdFtcZnJhY3tcZnJhY3tccGFydGlhbH17XHBhcnRpYWxcdGhldGF9TChcdGhldGE6XG1hdGhiZnt4fSkgfXtMKFx0aGV0YTogXG1hdGhiZnt4fSl9XHJpZ2h0XV4yLg0KJCQNCg0KDQpUaGlzIG1lYW5zIHdlIGNhbiBhbHNvIGRlZmluZSB0aGUgRmlzaGVyIEluZm9ybWF0aW9uIG51bWJlciBjYW4gYWxzbyBiZSBkZXJpdmVkIGFzDQoNCiQkDQpJX24oXHRoZXRhKSA9IC0gRSBcbGVmdFx7XGZyYWN7XHBhcnRpYWxeMn17XHBhcnRpYWwgXHRoZXRhXjJ9XGxlZnRbIFxsb2cgTChcdGhldGE6IFxtYXRoYmZ7eH0pIFxyaWdodF1ccmlnaHRcfS4gDQokJA0KDQpUaGlzIG1lYW5zIHRoYXQgdGhlIEZpc2hlciBJbmZvcm1hdGlvbiBudW1iZXIgaXMgdGhlIG5lZ2F0aXZlIGV4cGVjdGF0aW9uIG9mIHRoZSBzZWNvbmQtb3JkZXIgZGVyaXZhdGl2ZSBvZiB0aGUgbG9nLWxpa2VsaWhvb2QuDQoNClwNCg0KU2luY2Ugd2UgYXNzdW1lIGFuIElJRCBzYW1wbGUgaW4gbW9zdCBjYXNlcywgd2UgY2FuIGRlcml2ZSB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIEZpc2hlciBpbmZvcm1hdGlvbiBudW1iZXIgYXNzb2NpYXRlZCB3aXRoIHRoZSBlbnRpcmUgb2JzZXJ2ZWQgZGF0YSBzZXQgYW5kIHRoYXQgYmFzZWQgb24gdGhlIGluZGl2aWR1YWwgb2JzZXJ2YXRpb24gaW4gdGhlIGRhdGEgc2V0LiBEZW5vdGUgJElfMChcdGhldGEpJCBhcyB0aGUgRmlzaGVyIGluZm9ybWF0aW9uIG51bWJlciBvZiBhIHNpbmdsZSBvYnNlcnZhdGlvbiBvZiBhbiBJSUQgc2FtcGxlLg0KDQokJA0KSV9uKFx0aGV0YSkgPSAtIEUgXGxlZnRce1xmcmFje1xwYXJ0aWFsXjJ9e1xwYXJ0aWFsIFx0aGV0YV4yfVxsZWZ0WyBcbG9nIEwoXHRoZXRhOiBcbWF0aGJme3h9KSBccmlnaHRdXHJpZ2h0XH0gPSAtRVxsZWZ0XHtcZnJhY3tccGFydGlhbF4yfXtccGFydGlhbCBcdGhldGFeMn1cbGVmdFtcc3VtX3tpPTF9Xm4gXGxvZyBmKFx0aGV0YTogeF9pKSBccmlnaHRdXHJpZ2h0XH0NCiQkDQoNCiQkDQo9IFxzdW1fe2k9MX1ebiBcbGVmdFx7LSBFXGxlZnRbXGZyYWN7XHBhcnRpYWxeMn17XHBhcnRpYWwgXHRoZXRhXjJ9ICBcbG9nIGYoXHRoZXRhOiB4X2kpIFxyaWdodF0gXHJpZ2h0XH0gPSBuSV8wKFx0aGV0YSkuDQokJA0KDQoNCg0KKipSZW1hcmtzKiogU29tZSBjb21tZW50cyBvbiB0aGUgRmlzaGVyIEluZm9ybWF0aW9uOiANCg0KMS4gVGhlIEZpc2hlciBpbmZvcm1hdGlvbiBpcyBvbmx5IGEgZnVuY3Rpb24gb2YgdGhlIHBhcmFtZXRlciBzaW5jZSBpdCBpcyBkZWZpbmVkIGFzIGFuIGV4cGVjdGF0aW9uICh3aXRoIHJlc3BlY3QgdG8gJFxtYXRoYmZ7WH0kKSBvZiB0aGUgbG9nLWxpa2VsaWhvb2QuDQoNCjIuIElmIHdlIHJlcGxhY2UgdGhlIHBhcmFtZXRlciB3aXRoIGFuIGVzdGltYXRlZCBvbmUgc3VjaCBhcyBNTEUsIHdlIG9idGFpbiAkXHdpZGVoYXR7SV9uKFx0aGV0YSl9ID0gSV9uKFxoYXR7XHRoZXRhfSkkLiAgPGZvbnQgY29sb3IgPSAicmVkIj4qKlxjb2xvcntyZWR9JFx3aWRlaGF0e0lfbihcdGhldGEpfSQgaXMgY2FsbGVkIG9ic2VydmVkIEZpc2hlciBpbmZvcm1hdGlvbiBudW1iZXIhKio8L2ZvbnQ+DQoNCjMuIDxmb250IGNvbG9yID0gInJlZCI+KipcY29sb3J7cmVkfVRoZSBGaXNoZXIgaW5mb3JtYXRpb24gbnVtYmVyIGlzIGFsd2F5cyBwb3NpdGl2ZS4qKjwvZm9udD4NCg0KNC4gVGhlIEZpc2hlciBpbmZvcm1hdGlvbiBudW1iZXIgaXMgZGVwZW5kZW50IG9uIHRoZSBzYW1wbGUgc2l6ZS4gVGhpcyB3aWxsIGJlIHVzZWQgaW4gZGV2ZWxvcGluZyB0aGUgYXN5bXB0b3RpYyBub3JtYWxpdHkgZm9yIHRoZSBNTEUgaW4gdGhlIG5leHQgc2VjdGlvbi4NCg0KXA0KDQoqKkV4YW1wbGUqKjogQ29uc2lkZXIgYW4gSUlEIHNhbXBsZSAkXHt4XzEsIHhfMiwgXGNkb3RzLCB4X25cfSBcc2ltIGYoeCxcdGhldGEpID0gXHRoZXRhIGVeey1cdGhldGEgeH0kLiBGaW5kIHRoZSBGaXNoZXIgaW5mb3JtYXRpb24gbnVtYmVyLg0KDQpOb3RlIHRoYXQgdGhlIGxvZy1saWtlbGlob29kIGZ1bmN0aW9uIG9mICRcdGhldGEkIGlzIGdpdmVuIGJ5DQoNCiQkDQpsKFx0aGV0YTogXG1hdGhiZnt4fSkgPSBuIFxsb2cgXHRoZXRhIC1cdGhldGEgXHN1bV97aT0xfV5uIHhfaS4NCiQkDQoNClRoZSBzZWNvbmQgb3JkZXIgZGVyaXZhdGl2ZSBvZiAkbChcdGhldGEpJCB3aXRoIHJlc3BlY3QgdG8gJFx0aGV0YSQgaXMNCg0KJCQNClxmcmFje1xwYXJ0aWFsXjJ9e1xwYXJ0aWFsIFx0aGV0YV4yfSBsKFx0aGV0YSkgPSBcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXHRoZXRhfVxsZWZ0KCBcZnJhY3tufXtcdGhldGF9IC0gXHN1bV97aT0xfV5uIHhfaSBccmlnaHQpID0gLVxmcmFje259e1x0aGV0YV4yfS4NCiQkDQoNCkJ5IGRlZmluaXRpb24sDQoNCiQkDQpJX24oXHRoZXRhKSA9IC1FXGxlZnQoIFxmcmFje1xwYXJ0aWFsXjJ9e1xwYXJ0aWFsIFx0aGV0YV4yfSBsKFx0aGV0YSwgXG1hdGhiZnt4fSlccmlnaHQpID0gLUUoLVxmcmFje259e1x0aGV0YV4yfSkgPSBcZnJhY3tufXtcdGhldGFeMn0uDQokJA0KDQpUaGUgZXhwb25lbnRpYWwgZGVuc2l0eSBmdW5jdGlvbiBoYXMgYW5vdGhlciBmb3JtIChpLmUuLCByZXBhcmFtZXRyaXphdGlvbikgJGYoeCxcYmV0YSkgPSBcZnJhY3sxfXtcYmV0YX0gZV57LXgvXGJldGF9JC4gQSBuYXR1cmFsIHF1ZXN0aW9uIGlzIHdoZXRoZXIgd2UgbmVlZCB0byByZXBlYXQgdGhlIHNhbWUgY2FsY3VsYXRpb24gaW4gdGhlIGFib3ZlIGV4YW1wbGUgdG8gZmluZCB0aGUgRmlzaGVyIGluZm9ybWF0aW9uICRJX24oXGJldGEpJC4gVGhlIGFuc3dlciBpcyB1bm5lY2Vzc2FyeS4gIFdlIGNhbiAqcmVwYXJhbWV0cml6YXRpb24qIGluIHRoZSBGaXNoZXIgaW5mb3JtYXRpb24gbnVtYmVyLiANCg0KTGV0ICRcZXRhID0gXHBzaShcdGhldGEpJCBhbmQgJFxwc2koXGNkb3QpJCBpcyBpbnZlcnRpYmxlLCB0aGF0IGlzLCAkXHRoZXRhID0gXHBzaV57LTF9KFxldGEpJCBleGlzdHMuIEFzc3VtZSB0aGF0IHR3byBkZW5zaXR5IGZvcm1zIG9mICRYJCBhcmUgJGYoeCwgXHRoZXRhKSQgYW5kICRnKHgsIFxldGEpJC4gQ2xlYXJseSwgJGcoeCwgXGV0YSkgPSBmKHgsIFxwc2leey0xfShcZXRhKSkkIDxmb250IGNvbG9yID0gInJlZCI+Kih3aHk/KSo8L2ZvbnQ+LiAgQXNzdW1lIGZ1cnRoZXIgdGhhdCAkSV9uKFx0aGV0YSkgPSBJX25bXHBzaV57LTF9KFxldGEpXSQgaXMga25vd24uIA0KDQpEdWUgdG8gcmVwYXJhbWV0cml6YXRpb24sIHRoZSBzYW1lIHJhbmRvbSB2YXJpYWJsZSBoYXMgZGlmZmVyZW50IGZvcm1zIG9mIGRlbnNpdHkgZnVuY3Rpb24uIFdoZW4gd2Ugd29yayBvbiB0aGUgZXhwZWN0YXRpb24gd2l0aCB0aGUgcmFuZG9tIHZhcmlhYmxlLCB3ZSBzaG91bGQgc3BlY2lmeSB0aGUgYXNzb2NpYXRlZCBkZW5zaXR5IGZ1bmN0aW9uLiBOZXh0LCB3ZSBleHByZXNzICRJX2coXGV0YSkkIHdpdGggcmVzcGVjdCB0byAkSV9mKFx0aGV0YSkkLiANCg0KJCQNCklfe24sZ30oXGV0YSkgPSBFX2dcbGVmdFsgXGxlZnQoXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFxldGF9IFxsb2cgZyh4LCBcZXRhKSAgXHJpZ2h0KV4yIFxyaWdodF0gPSBFX2dcbGVmdFsgXGxlZnQoXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFxldGF9IFxsb2cgZih4LCBccHNpXnstMX0oXGV0YSkpICBccmlnaHQpXjIgXHJpZ2h0XQ0KJCQNCg0KJCQNCj0gRV9nXGxlZnRbIFxsZWZ0KFxmcmFje1xwYXJ0aWFsfXtccGFydGlhbCBcZXRhfSBcbG9nIGYoeCwgXHBzaV57LTF9KFxldGEpKSBcdGltZXMgXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFxldGF9IFxwc2leey0xfShcZXRhKVxyaWdodCleMiBccmlnaHRdDQokJA0KDQokJA0KPSBFX2dcbGVmdFsgXGxlZnQoXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFxldGF9IFxsb2cgZih4LCBccHNpXnstMX0oXGV0YSkpIFxyaWdodCleMiBcdGltZXMgXGxlZnQoXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFxldGF9IFxwc2leey0xfShcZXRhKVxyaWdodCleMiBccmlnaHRdDQokJA0KDQokJA0KPSBFX2dcbGVmdFsgXGxlZnQoXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFxldGF9IFxsb2cgZih4LCBccHNpXnstMX0oXGV0YSkpIFxyaWdodCleMiAgXHJpZ2h0XVx0aW1lcyBcbGVmdChcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXGV0YX0gXHBzaV57LTF9KFxldGEpXHJpZ2h0KV4yID0gSV97bixmfShcdGhldGEpXHRpbWVzIFxsZWZ0KFxmcmFje1xwYXJ0aWFsfXtccGFydGlhbCBcZXRhfSBccHNpXnstMX0oXGV0YSlccmlnaHQpXjIuDQokJA0KDQpUaGF0IGlzLA0KDQokJA0KSV97bixnfShcZXRhKT1JX3tuLGZ9KFx0aGV0YSlcdGltZXMgXGxlZnQoXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFxldGF9IFxwc2leey0xfShcZXRhKVxyaWdodCleMi4NCiQkDQoNCg0KDQojIyMgRmlzaGVyIEluZm9ybWF0aW9uIE1hdHJpeA0KDQpGb3IgbXVsdGktcGFyYW1ldGVyIG1vZGVscyAoZGlzdHJpYnV0aW9ucyksIHdlIG5lZWQgYSBGaXNoZXIgaW5mb3JtYXRpb24gbWF0cml4IHRvIGNoYXJhY3Rlcml6ZSB0aGUgY292YXJpYW5jZSBzdHJ1Y3R1cmUgb2YgdGhlIE1MRSBvZiB0aGUgdmVjdG9yIG9mIG11bHRpcGxlIHBhcmFtZXRlcnMuIERlbm90ZSAkZih4OyBcbWF0aGJme1x0aGV0YX0pJCBiZSB0aGUgZGVuc2l0eSBmdW5jdGlvbiBvZiAkWCQgd2l0aCBhIGstZGltZW5zaW9uYWwgcGFyYW1ldGVycyAkXG1hdGhiZntcdGhldGF9ID0gKFx0aGV0YV8xLCBcdGhldGFfMiwgXGNkb3RzLCBcdGhldGFfaykkIDxmb250IGNvbG9yID0gInJlZCI+ICpcY29sb3J7cmVkfShDYXV0aW9uOiBpZiBub3Qgc3BlY2lmaWVkLCBhbGwgdmVjdG9ycyBpbiB0aGlzIHNlcmllcyBvZiBub3RlIGFyZSBjb2x1bW4gdmVjdG9ycy4gVGhpcyBpcyBhbHNvIHRydWUgaW4gbW9zdCBtYXRoZW1hdGljcyBhbmQgc3RhdGlzdGljcyBib29rcyBhbmQgbGl0ZXJhdHVyZSkqPC9mb250Pg0KDQpVbmRlciB0aGUgc2FtZSBzZXR1cCwgdGhlIGxpa2VsaWhvb2QgZnVuY3Rpb24gb2Ygb2JzZXJ2aW5nICRce3hfMSwgeF8yLCBcY2RvdHMsIHhfbiBcfVxzaW0gZih4LCBcbWF0aGJme1x0aGV0YX0pJCBpcyBnaXZlbiBieSANCg0KJCQNCkwoXG1hdGhiZntcdGhldGF9OlxtYXRoYmZ7eH0pID0gXHByb2Rfe2k9MX1ebiBmKHhfaSwgXG1hdGhiZntcdGhldGF9KQ0KJCQNCg0KVGhlIGdyYWRpZW50IHZlY3RvciBvZiB0aGUgbG9nLWxpa2VsaWhvb2QgaXMgDQoNCiQkDQpcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXHRoZXRhfSBcbG9nIEwoXHRoZXRhLCBcbWF0aGJme3h9KSA9IFxsZWZ0KCBcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXHRoZXRhXzF9IFxsb2cgTChcdGhldGEsIFxtYXRoYmZ7eH0pLCAgXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFx0aGV0YV8yfSBcbG9nIEwoXHRoZXRhLCBcbWF0aGJme3h9KSwgXGNkb3RzLCBcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXHRoZXRhX2t9IFxsb2cgTChcdGhldGEsIFxtYXRoYmZ7eH0pLFxyaWdodCkuDQokJA0KDQpEZW5vdGUNCg0KJCQNClxmcmFje1xwYXJ0aWFsfXtccGFydGlhbCBcdGhldGFeVH0gXGxvZyBMKFx0aGV0YSwgXG1hdGhiZnt4fSkgPSBcbGVmdCggXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFx0aGV0YV8xfSBcbG9nIEwoXHRoZXRhLCBcbWF0aGJme3h9KSwgIFxmcmFje1xwYXJ0aWFsfXtccGFydGlhbCBcdGhldGFfMn0gXGxvZyBMKFx0aGV0YSwgXG1hdGhiZnt4fSksIFxjZG90cywgXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFx0aGV0YV9rfSBcbG9nIEwoXHRoZXRhLCBcbWF0aGJme3h9KSxccmlnaHQpXlQNCiQkDQoNClRoZSAqKkZpc2hlciBpbmZvcm1hdGlvbiBtYXRyaXgqKiBvZiB0aGUgay1kaW1lbnNpb25hbCBwYXJhbWV0ZXIgJFx0aGV0YSQgaXMgZGVmaW5lZCB0byBiZQ0KDQokJA0KXG1hdGhiYntJfV9uKFxtYXRoYmZ7XHRoZXRhfSkgPSBFXGxlZnQoIFxmcmFje1xwYXJ0aWFsfXtccGFydGlhbCBcdGhldGF9IFxsb2cgTChcdGhldGEsIFxtYXRoYmZ7eH0pXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFx0aGV0YV5UfSBcbG9nIEwoXHRoZXRhLCBcbWF0aGJme3h9KSBccmlnaHQpLg0KJCQNCg0KVGhlIGV4cGxpY2l0IG1hdHJpeCBmb3JtIG9mIHRoZSB0d28tcGFyYW1ldGVyIGNhc2UgaXMNCg0KJCQNClxtYXRoYmJ7SX1fbihcbWF0aGJme1x0aGV0YX0pID0gRSBcbGVmdFtcbGVmdCggXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFx0aGV0YV8xfSBcbG9nIEwoXHRoZXRhLCBcbWF0aGJme3h9KSwgXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFx0aGV0YV8yfSBcbG9nIEwoXHRoZXRhLCBcbWF0aGJme3h9KSBccmlnaHQpIFxsZWZ0KCBcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXHRoZXRhXzF9IFxsb2cgTChcdGhldGEsIFxtYXRoYmZ7eH0pLCBcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXHRoZXRhXzJ9IFxsb2cgTChcdGhldGEsIFxtYXRoYmZ7eH0pIFxyaWdodCleVFxyaWdodF0NCiQkDQoNCg0KJCQNCj0gRSBcYmVnaW57Ym1hdHJpeH0NCiAgICBcbGVmdChcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXHRoZXRhXzF9IFxsb2cgTChcdGhldGEsIFxtYXRoYmZ7eH0pIFxyaWdodCleMiAmIFxmcmFje1xwYXJ0aWFsfXtccGFydGlhbCBcdGhldGFfMX0gXGxvZyBMKFx0aGV0YSwgXG1hdGhiZnt4fSlcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXHRoZXRhXzJ9IFxsb2cgTChcdGhldGEsIFxtYXRoYmZ7eH0pICBcXA0KICAgIFxmcmFje1xwYXJ0aWFsfXtccGFydGlhbCBcdGhldGFfMX0gXGxvZyBMKFx0aGV0YSwgXG1hdGhiZnt4fSlcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXHRoZXRhXzJ9IFxsb2cgTChcdGhldGEsIFxtYXRoYmZ7eH0pICYgXGxlZnQoXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFx0aGV0YV8yfSBcbG9nIEwoXHRoZXRhLCBcbWF0aGJme3h9KSBccmlnaHQpXjINClxlbmR7Ym1hdHJpeH0uDQokJA0KDQo8Zm9udCBjb2xvciA9ICJyZWQiPioqXGNvbG9ye3JlZH0gUmVtYXJrcyoqPC9mb250Pg0KDQoxLiBUaGUgRmlzaGVyIGluZm9ybWF0aW9uIG1hdHJpeCBpcyBhIDxmb250IGNvbG9yID0gInJlZCI+KipzcXVhcmUgbWF0cml4Kio8L2ZvbnQ+LiBJdHMgZGltZW5zaW9uIGlzIGRlcGVuZGVudCBvbiB0aGUgZGltZW5zaW9uIG9mIHRoZSB2ZWN0b3Igb2YgcGFyYW1ldGVycy4gRm9yIHRoZSBjYXNlIG9mIGEgay1kaW1lbnNpb25hbCBwYXJhbWV0ZXIgdmVjdG9yLCB0aGUgZGltZW5zaW9uIG9mIHRoZSBjb3JyZXNwb25kaW5nIEZpc2hlciBpbmZvcm1hdGlvbiBtYXRyaXggaXMgJGtcdGltZXMgayQuIA0KDQoyLiBUaGUgaW5kaXZpZHVhbCBjZWxsIGVsZW1lbnQgaW4gdGhlIEZpc2hlciBpbmZvcm1hdGlvbiBtYXRyaXggaXMgZXhwcmVzc2VkIGluIHRoZSBmb2xsb3dpbmcNCg0KJCQNCltcbWF0aGJie0l9X24oXG1hdGhiZntcdGhldGF9KV1fe2ksan0gPSBcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXHRoZXRhX2l9IFxsb2cgTChcdGhldGEsIFxtYXRoYmZ7eH0pXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFx0aGV0YV9qfSBcbG9nIEwoXHRoZXRhLCBcbWF0aGJme3h9KSANCiQkDQoNCg0KMy4gVGhlIEZpc2hlciBpbmZvcm1hdGlvbiBtYXRyaXggaXMgdGhlIGNvdmFyaWFuY2UgbWF0cml4IG9mIHRoZSBncmFkaWVudCB2ZWN0b3IgJFxwYXJ0aWFsIFxsb2cgTChcdGhldGE6IFxtYXRoYmZ7eH0pL1xwYXJ0aWFsIFx0aGV0YSQuDQoNCjQuIFRoZSBGaXNoZXIgaW5mb3JtYXRpb24gYXQgZWFjaCBpbmRpdmlkdWFsIG9ic2VydmVkIGRhdGEgcG9pbnQgJHhfaSQgaXMgc3RpbGwgYSAka1x0aW1lcyBrJCBzcXVhcmUgbWF0cml4IGFuZCBpcyBzaW1pbGFybHkgZ2l2ZW4gYnkNCg0KJCQNCklfMChcdGhldGEpPSBFIFxiZWdpbntibWF0cml4fQ0KICAgIFxsZWZ0KFxmcmFje1xwYXJ0aWFsfXtccGFydGlhbCBcdGhldGFfMX0gXGxvZyBMKFx0aGV0YSwgeF9pKSBccmlnaHQpXjIgJiBcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXHRoZXRhXzF9IFxsb2cgTChcdGhldGEsIHhfaSlcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXHRoZXRhXzJ9IFxsb2cgTChcdGhldGEsIHhfaSkgIFxcDQogICAgXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFx0aGV0YV8xfSBcbG9nIEwoXHRoZXRhLCB4X2kpXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFx0aGV0YV8yfSBcbG9nIEwoXHRoZXRhLCB4X2kpICYgXGxlZnQoXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFx0aGV0YV8yfSBcbG9nIEwoXHRoZXRhLCB4X2kpIFxyaWdodCleMg0KXGVuZHtibWF0cml4fS4NCiQkDQoNCjUuIEZvciBhbiBJSUQgc2FtcGxlICRce3hfMSwgeF8yLCBcY2RvdHMsIHhfblx9IFxzaW0gZihcbWF0aGJme3h9OiBcdGhldGEpJCwNCg0KJCQNCklfbihcdGhldGEpID0gbklfMChcdGhldGEpLg0KJCQNCg0KKkFuYWxvZ291cyB0byB0aGUgY2FzZSBvZiBzaW5nbGUgcGFyYW1ldGVyIGRpc3RyaWJ1dGlvbnMsIHdlIGFsc28gaGF2ZSB0aGUgZm9sbG93aW5nIGFsdGVybmF0aXZlIGRlZmluaXRpb24gb2YgdGhlIEZpc2hlciBpbmZvcm1hdGlvbiBtYXRyaXggZm9yIG11bHRpLXBhcmFtZXRlciBkaXN0cmlidXRpb25zKg0KDQokJA0KXG1hdGhiYntJfV9uKFxtYXRoYmZ7XHRoZXRhfSkgPSAtRVxsZWZ0KCBcZnJhY3tccGFydGlhbF4yfXtccGFydGlhbCBcdGhldGEgXHBhcnRpYWwgXHRoZXRhXlR9IFxsb2cgTChcdGhldGE6XG1hdGhiZnt4fSlccmlnaHQpLg0KJCQNCg0Kd2hlcmUNCg0KJCQNClxtYXRoYmJ7SH1fbihcdGhldGEsIFxtYXRoYmZ7eH0pPVxmcmFje1xwYXJ0aWFsXjJ9e1xwYXJ0aWFsIFx0aGV0YSBccGFydGlhbCBcdGhldGFeVH0gXGxvZyBMKFx0aGV0YTpcbWF0aGJme3h9KSA9DQpcYmVnaW57Ym1hdHJpeH0NCiAgICAgXGZyYWN7XHBhcnRpYWxeMn17XHBhcnRpYWwgXHRoZXRhXzFeMn0gXGxvZyBMKFx0aGV0YSwgeF9pKSAmIFxmcmFje1xwYXJ0aWFsXjJ9e1xwYXJ0aWFsIFx0aGV0YV8xIFxwYXJ0aWFsIFx0aGV0YV8yfSBcbG9nIEwoXHRoZXRhLCB4X2kpICAmIFxjZG90cyAmIFxmcmFje1xwYXJ0aWFsXjJ9e1xwYXJ0aWFsIFx0aGV0YV8xIFxwYXJ0aWFsIFx0aGV0YV9rfSBcbG9nIEwoXHRoZXRhLCB4X2kpICBcXA0KICAgIFxmcmFje1xwYXJ0aWFsXjJ9e1xwYXJ0aWFsIFx0aGV0YV8yIFxwYXJ0aWFsIFx0aGV0YV8xfSBcbG9nIEwoXHRoZXRhLCB4X2kpKSAmIFxmcmFje1xwYXJ0aWFsXjJ9e1xwYXJ0aWFsIFx0aGV0YV8yXjJ9IFxsb2cgTChcdGhldGEsIHhfaSkgICAmIFxjZG90cyAmIFxmcmFje1xwYXJ0aWFsXjJ9e1xwYXJ0aWFsIFx0aGV0YV8yIFxwYXJ0aWFsIFx0aGV0YV9rfSBcbG9nIEwoXHRoZXRhLCB4X2kpICBcXA0KICAgIFx2ZG90cyAmIFx2ZG90cyAmIFx2ZG90cyBcXA0KICAgIFxmcmFje1xwYXJ0aWFsXjJ9e1xwYXJ0aWFsIFx0aGV0YV9rIFxwYXJ0aWFsIFx0aGV0YV8xfSBcbG9nIEwoXHRoZXRhLCB4X2kpJiBcZnJhY3tccGFydGlhbF4yfXtccGFydGlhbCBcdGhldGFfayBccGFydGlhbCBcdGhldGFfMn0gXGxvZyBMKFx0aGV0YSwgeF9pKSAmIFxjZG90cyAmICBcZnJhY3tccGFydGlhbF4yfXtccGFydGlhbCBcdGhldGFfa14yIH0gXGxvZyBMKFx0aGV0YSwgeF9pKSANClxlbmR7Ym1hdHJpeH1fe2tcdGltZXMga30NCiQkDQoNCmlzIHRoZSB3ZWxsLWtub3duICoqSGVzc2lhbiBtYXRyaXgqKi4gKipIZXNzaWFuIE1hdHJpY2VzKiogYXJlIHdpZGVseSB1c2VkIGluIG9wdGltaXphdGlvbiBwcm9ibGVtcy4gDQoNCg0KPGZvbnQgY29sb3IgPSAicmVkIj4qKlxjb2xvcntyZWR9Q2F1dGlvbioqPC9mb250PjogICoqSGVzc2lhbiBNYXRyaXggYW5kIEphY29iaWFuIE1hdHJpeCoqIGFyZSBzb21ldGltZXMgY29uZnVzaW5nLiANCg0KMS4gVGhlICoqSGVzc2lhbiBtYXRyaXgqKiBpcyB0aGUgc3F1YXJlIG1hdHJpeCBvZiBzZWNvbmQtb3JkZXIgcGFydGlhbCBkZXJpdmF0aXZlcyBvZiB0aGUgb2JqZWN0aXZlIGZ1bmN0aW9uIHRvIGJlIG9wdGltaXplZC4NCg0KMi4gVGhlICoqSmFjb2JpYW4gbWF0cml4KiogaXMgdGhlIGZpcnN0LW9yZGVyIGRlcml2YXRpdmVzIG9mIGEgdmVjdG9yIG9mIGZ1bmN0aW9ucyBzdWNoIGFzICQoZl8xKFx0aGV0YSksIGZfMihcdGhldGEpLCBcY2RvdHMsIGZfayhcdGhldGEpKSQgd2hlcmUgJFx0aGV0YSA9IChcdGhldGFfMSwgXHRoZXRhXzIsIFxjZG90cywgXHRoZXRhX2spJC4gVGhlICoqSmFjb2JpYW4gbWF0cml4KiogYXNzb2NpYXRlZCB3aXRoIHRoZSB2ZWN0b3Igb2YgZnVuY3Rpb25zIGlzIGRlZmluZWQgYnkNCg0KJCQNCkooXHRoZXRhKSA9IFxiZWdpbntibWF0cml4fQ0KICAgICBcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXHRoZXRhXzF9IGZfMShcdGhldGEpICYgXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFx0aGV0YV8yfSBmXzEoXHRoZXRhKSAgJiBcY2RvdHMgJiBcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXHRoZXRhX2t9IGZfMShcdGhldGEpIFxcDQogICAgXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFx0aGV0YV8xfSBmXzIoXHRoZXRhKSAmIFxmcmFje1xwYXJ0aWFsfXtccGFydGlhbCBcdGhldGFfMn0gZl8yKFx0aGV0YSkgICYgXGNkb3RzICYgXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFx0aGV0YV9rfSBmXzIoXHRoZXRhKSAgXFwNCiAgICBcdmRvdHMgJiBcdmRvdHMgJiBcdmRvdHMgXFwNCiAgICBcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXHRoZXRhXzF9IGZfayhcdGhldGEpICYgXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFx0aGV0YV8yfSBmX2soXHRoZXRhKSAgJiBcY2RvdHMgJiBcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXHRoZXRhX2t9IGZfayhcdGhldGEpDQpcZW5ke2JtYXRyaXh9X3trXHRpbWVzIGt9DQokJA0KDQozLiBXaGVuIGZpbmRpbmcgdGhlIE1MRSBvZiB1bmtub3duIHBhcmFtZXRlcnMgZnJvbSB0aGUgb2JqZWN0aXZlIGxvZy1saWtlbGlob29kIGZ1bmN0aW9uICRsKFx0aGV0YSkkLCB3ZSBmaXJzdCBjYWxjdWxhdGUgZ3JhZGllbnQgZnVuY3Rpb25zIA0KDQokJA0KXGxlZnQoXGZyYWN7XHBhcnRpYWwgbChcdGhldGEpfXtccGFydGlhbCBcdGhldGFfMX0sIFxmcmFje1xwYXJ0aWFsIGwoXHRoZXRhKX17XHBhcnRpYWwgXHRoZXRhXzJ9LCBcY2RvdHMsIFxmcmFje1xwYXJ0aWFsIGwoXHRoZXRhKX17XHBhcnRpYWwgXHRoZXRhX2t9XHJpZ2h0KSBcc3RhY2tyZWx7XHRleHR7ZGVmfX17XGVxdWl2fSBbZl8xKFx0aGV0YSksIGZfMihcdGhldGEpLCBcY2RvdHMsIGZfayhcdGhldGEpXQ0KJCQNCg0KJFxoc3BhY2V7NW1tfSQgIFRoZW4gdGhlICoqSGVzc2lhbiBNYXRyaXgqKiBhc3NvY2lhdGVkIHdpdGggdGhlIG9iamVjdGl2ZSBmdW5jdGlvbiAkbChcdGhldGEpJCBhbmQgdGhlICoqSmFjb2JpYW4gTWF0cml4KiogIGFzc29jaWF0ZWQgd2l0aCBncmFkaWVudCAoc2NvcmUpIGZ1bmN0aW9ucyA8Zm9udCBjb2xvciA9ICJyZWQiPioqXGNvbG9ye3JlZH1hcmUgaWRlbnRpY2FsKio8L2ZvbnQ+Lg0KDQoNCiMjIE11bHRpcGxlIFJhbmRvbSBWYXJpYWJsZXMgYW5kIFJhbmRvbSBWZWN0b3JzDQoNCldlIGZpcnN0IGludHJvZHVjZSB0aGUgY29uY2VwdCBvZiBjb3ZhcmlhbmNlIGFuZCBwcm9wZXJ0aWVzIGFzc29jaWF0ZWQgd2l0aCBtdWx0aXBsZSByYW5kb20gdmFyaWFibGVzLg0KDQpMZXQgJFgkIGFuZCAkWSQgYmUgdHdvIHZhcmlhYmxlcywgdGhlIGNvdmFyaWFuY2UgdGhhdCBtZWFzdXJlcyB0aGUgbGluZWFyIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHR3byByYW5kb20gdmFyaWFibGVzIGlzIGRlZmluZWQgYnkNCg0KJCQNClx0ZXh0e2Nvdn0oWCxZKSA9IEVce1tYLUUoWCldW1ktRShZKV1cfS4NCiQkDQoNCioqU29tZSBwcm9wZXJ0aWVzIG9mIGNvdmFyaWFuY2UqKjoNCg0KMS4gJFx0ZXh0e2Nvdn0oWCxZKSA9IFx0ZXh0e2Nvdn0oWSxYKSQuDQoNCjIuIFdoZW4gJFggPSBZJCwgJFx0ZXh0e2Nvdn0oWCxZKSA9IFx0ZXh0e3Zhcn0oWCkkLg0KDQozLiBMZXQgJGEkIGFuZCAkYiQgYXJlIHNjYWxhcnMsIA0KDQogICsgJFx0ZXh0e2Nvdn0oYVgsIFkpID0gYSBcdGltZXMgXHRleHR7Y292fShYLFkpJDsNCiAgKyAkXHRleHR7Y292fShhWCwgYlkpID0gYWIgXHRpbWVzIFx0ZXh0e2Nvdn0oWCxZKSQ7DQogICsgJFx0ZXh0e2Nvdn0oYVggKyBiLCBZKSA9IGFcdGltZXMgXHRleHR7Y292fShYLFkpJA0KDQozLiBMZXQgJFogPSBhWCArIGJZJCwgJEUoWikgPSBFW2FYICsgYlldID0gYUVbWF0gKyBiRVtZXSQgYW5kICRcdGV4dHt2YXJ9KFopID0gYV4yXHRleHR7dmFyfShYKSA9IDJhYlxjZG90IFx0ZXh0e2Nvdn0oWCxZKSArIGJeMiBcdGV4dHt2YXJ9KFkpJC4gPGZvbnQgY29sb3IgPSAicmVkIj4qXGNvbG9ye3JlZH0gKFByb3ZlIHRoaXMgdXNpbmcgdGhlIGRlZmluaXRpb24gb2YgdGhlIHZhcmlhbmNlLikqPC9mb250Pg0KDQo0LiBUaGUgKCpsaW5lYXIqKSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCBiZXR3ZWVuICRYJCBhbmQgJFkkIGlzIGdpdmVuIGJ5DQokJA0KXHJobyA9IFxmcmFje1x0ZXh0e2Nvdn0oWCwgWSl9e1xzcXJ0e1x0ZXh0e3Zhcn0oWClcdGV4dHt2YXJ9KFkpfX0NCiQkDQoNCkZvciBhIGdpdmVuIHNhbXBsZSAkXHsoeF8xLCB5XzEpLCAoeF8yLCB5XzIpLCBcY2RvdHMsICh4X24sIHlfbikgXH0kLCB0aGUgc2FtcGxlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IGlzIGdpdmVuIGJ5DQoNCiQkDQpyID0gXGZyYWN7XGxlZnRbXHN1bV97aT0xfV5uICh4X2ktXGJhcnt4fSkoeV9pLVxiYXJ7eX0pXHJpZ2h0XS9ufXtcc3FydHtcZnJhY3tcc3VtX3tpPTF9Xm4gKHhfaS1cYmFye3h9KV4yfXtufVxmcmFje1xzdW1fe2k9MX1ebiAoeV9pLVxiYXJ7eX0pXjJ9e259fX0gPSBcZnJhY3tcc3VtX3tpPTF9Xm4gKHhfaS1cYmFye3h9KSh5X2ktXGJhcnt5fSl9e1xzcXJ0e1xzdW1fe2k9MX1ebiAoeF9pLVxiYXJ7eH0pXjJcc3VtX3tpPTF9Xm4gKHlfaS1cYmFye3l9KV4yfX0uDQokJA0KDQpUaGUgdmFyaWFuY2Ugb2YgdGhlIGxpbmVhciBjb21iaW5hdGlvbiBvZiByYW5kb20gdmFyaWFibGVzICRYJCBhbmQgJFkkLCAkWiA9IGFYICsgYlkkLCBpbnZvbHZlcyBjb3ZhcmlhbmNlIG9mICRYJCBhbmQgJFkkLiBJbiBnZW5lcmFsLCB3ZSBjYW4gY29uc2lkZXIgdGhlIGxpbmVhciBjb21iaW5hdGlvbiBvZiBhIHNlcXVlbmNlIG9mIHJhbmRvbSB2YXJpYWJsZXMgJFx7WF8xLCBYXzIsIFxjZG90cywgWF9wIFx9JCwgc2F5ICRXID0gXHN1bV97aT0xfV5wIGFfaVhfaSQsIHdlIGNhbiBjYWxjdWxhdGUgdGhlIHZhcmlhbmNlIG9mICRXJCBpbiB0aGUgZm9sbG93aW5nDQoNCiQkDQpcdGV4dHt2YXJ9KFcpID0gXHN1bV97aT0xfV5wIGFfaV4yIFx0ZXh0e3Zhcn0oWF9pKSArIFxzdW1fe2lcbmUgan0gYV9pYV9qIFx0ZXh0e2Nvdn0oWF9pLCBYX2opDQokJA0KDQpUaGUgYWJvdmUgdmFyaWFuY2Ugb2YgJFckIGlzIG9idGFpbmVkIGJhc2VkIG9uIHRoZSBkZWZpbml0aW9uIG9mIHZhcmlhbmNlIGFuZCBiaW5vbWlhbCBleHBhbnNpb24uIEhvd2V2ZXIsIHdlIGNhbiB3cml0ZSB0aGUgbGluZWFyIGNvbWJpbmF0aW9uIG9mIHRoZSByYW5kb20gdmFyaWFuY2UgaW4gdGhlIHZlY3RvciBmb3JtDQoNCiQkDQpXID0gKGFfMSwgYV8yLCBcY2RvdHMsIGFfcCkgXGJlZ2lue2JtYXRyaXh9DQogICAgICBYXzEgICAgXFwgDQogICAgICBYXzIgICAgXFwgDQogICAgICBcdmRvdHMgXFwgDQogICAgICBYX3ANClxlbmR7Ym1hdHJpeH0uDQokJA0KDQpUaGVyZWZvcmUsICRXJCBpcyB0aGUgZG90IHByb2R1Y3Qgb2YgYSBzY2FsYXIgdmVjdG9yIChjb2VmZmljaWVudCBvZiB0aGUgbGluZWFyIGNvbWJpbmF0aW9uKSBhbmQgYSByYW5kb20gdmVjdG9yLiBUaGlzIG1vdGl2YXRlcyB1cyB0byBzdHVkeSByYW5kb20gdmVjdG9ycy4NCg0KXA0KDQoqKlJhbmRvbSBWZWN0b3JzIGFuZCBQcm9wZXJ0aWVzKioNCg0KDQpXZSBoYXZlIGRpc2N1c3NlZCB0aGUgZGlzdHJpYnV0aW9uIG9mIHNpbmdsZSByYW5kb20gdmFyaWFibGVzIGFuZCB0aGUgcmVsYXRlZCBjaGFyYWN0ZXJpemF0aW9uLiBJZiB3ZSBoYXZlIGEgdmVjdG9yIG9mICRwJCByYW5kb20gdmFyaWFibGVzIA0KDQokJA0KXG1hdGhiZntYfSA9IFxiZWdpbntibWF0cml4fQ0KICAgICAgWF8xICAgIFxcIA0KICAgICAgWF8yICAgIFxcIA0KICAgICAgXHZkb3RzIFxcIA0KICAgICAgWF9wDQpcZW5ke2JtYXRyaXh9Lg0KJCQuIA0KDQpFYWNoIHJhbmRvbSB2YXJpYWJsZSBoYXMgc3VwcG9ydCAoaS5lLiwgZG9tYWluKSAkXG1hdGhiYntSfV9pIFxzdWJzZXRlcSBcbWF0aGJie1J9JCBmb3IgJGkgPSAxLCAyLCBcY2RvdHMsIHAkLiBMZXQgDQoNCiQkDQpcbWF0aGJme3h9ID0gXGJlZ2lue2JtYXRyaXh9DQogICAgICB4XzEgICAgXFwgDQogICAgICB4XzIgICAgXFwgDQogICAgICBcdmRvdHMgXFwgDQogICAgICB4X3ANClxlbmR7Ym1hdHJpeH0uDQokJC4gDQoNCmJlIHRoZSByZWFsaXphdGlvbiAoaS5lLiwgb2JzZXJ2ZWQgZGF0YSB2YWx1ZXMpIG9mIHJhbmRvbSB2YXJpYWJsZSAkXG1hdGhiYntYfSQuIFRoaXMgbWVhbnMNCg0KJCQNClxtYXRoYmZ7eH0gXGluIChcbWF0aGJie1J9XzEgXHRpbWVzIFxtYXRoYmJ7Un1fMiBcdGltZXMgXGNkb3RzIFx0aW1lcyBcbWF0aGJie1J9X3ApXlQuDQokJA0KDQpUaGUgKiptZWFuIG9mIHRoZSByYW5kb20gdmVjdG9yKiogaXMNCg0KJCQNCkUoXG1hdGhiZntYfSkgXHN0YWNrcmVse1x0ZXh0e2RlZn19e1xlcXVpdn0gXGJlZ2lue2JtYXRyaXh9DQogICAgICBFKFhfMSkgXFwgDQogICAgICBFKFhfMikgXFwgDQogICAgICBcdmRvdHMgXFwgDQogICAgICBFKFhfcCkNClxlbmR7Ym1hdHJpeH0NCj0gIFxiZWdpbntibWF0cml4fQ0KICAgICAgXG11XzEgIFxcIA0KICAgICAgXG11XzIgIFxcIA0KICAgICAgXHZkb3RzIFxcIA0KICAgICAgXG11X3ANClxlbmR7Ym1hdHJpeH0NCi4NCiQkDQoNClRoZSAqKnZhcmlhbmNlLWNvdmFyaWFuY2UgbWF0cml4KiogaXMgZGVmaW5lZCBieQ0KDQokJA0KVltcbWF0aGJme1h9XSBcc3RhY2tyZWx7XHRleHR7ZGVmfX17XGVxdWl2fSANClxiZWdpbntibWF0cml4fQ0KICAgICBcdGV4dHt2YXJ9IChYXzEpICYgXHRleHR7Y292fShYXzEsIFhfMikgICYgXGNkb3RzICYgXHRleHR7Y292fShYXzEsIFhfcCkgXFwNCiAgICAgXHRleHR7Y292fSAoWF8yLFhfMSkgJiBcdGV4dHt2YXJ9KFhfMikgICYgXGNkb3RzICYgXHRleHR7Y292fShYXzIsIFhfcCkgXFwNCiAgICAgXHZkb3RzICYgXHZkb3RzICYgXHZkb3RzICYgXHZkb3RzXFwNCiAgICAgXHRleHR7Y292fSAoWF9rLFhfMSkgJiBcdGV4dHtjb3Z9KFhfcCxYXzIpICAmIFxjZG90cyAmIFx0ZXh0e3Zhcn0oWF9wKSANClxlbmR7Ym1hdHJpeH1fe3BcdGltZXMgcH0NCiQkDQoNCioqU29tZSBQcm9wZXJ0aWVzIG9mIFJhbmRvbSBWZWN0b3JzKioNCg0KMS4gQSBjb25zdGFudCB2ZWN0b3IgYSAodmVjdG9yIG9mIGNvbnN0YW50cykgc2F0aXNmaWVzICRFW2FdID0gYSQuDQoNCjIuIEZvciByYW5kb20gdmVjdG9ycyAkXG1hdGhiZntYfSQgYW5kICRcbWF0aGJme1l9JCwgJEVbXG1hdGhiZntYfSArIFxtYXRoYmZ7WX1dID0gRVtcbWF0aGJme1h9XSArIEVbXG1hdGhiZntZfV0kDQoNCjMuIExldCAkXG1hdGhiZnthfSQgYmUgYSBzY2FsYXIgKGNvbHVtbikgdmVjdG9yIGFuZCAkXG1hdGhiZntYfSQgYmUgYSAoY29sdW1uKSByYW5kb20gdmVjdG9yLiAkXG1hdGhiZnthfV5UXG1hdGhiZntYfSQgaXMgd2VsbCBkZWZpbmVkLiBUaGVuICRcdGV4dHt2YXJ9KFxtYXRoYmZ7YX1eVFxtYXRoYmZ7WH0pID0gXG1hdGhiZnthfV5UXHRleHR7Y292fShcbWF0aGJme1h9KVxtYXRoYmZ7YX0kLg0KDQoqKkV4YW1wbGUqKiBEZXJpdmUgdGhlIHZhcmlhbmNlIG9mICRaID0gYVggKyBiWSQgdXNpbmcgdGhlIHByb3BlcnRpZXMgb2YgcmFuZG9tIHZlY3RvcnMuIExldCAkXG1hdGhiZntkfSA9IChhLGIpJA0KDQokJA0KXHRleHR7dmFyfShaKSA9IFx0ZXh0e3Zhcn0oXG1hdGhiZntkfV5UXG1hdGhiZntafSkgPSBcbWF0aGJme2R9XlRcdGV4dHtjb3Z9KFxtYXRoYmZ7Wn0pXG1hdGhiZntkfQ0KJCQNCg0KJCQNCj0gW2EsYl1cYmVnaW57Ym1hdHJpeH0NCiAgICAgICBcdGV4dHt2YXJ9KFgpICAgJiAgXHRleHR7Y292fShYLFkpIFxcDQogICAgICAgXHRleHR7Y292fShZLCBYKSAmIFx0ZXh0e3Zhcn0oWSkNCiAgICAgIFxlbmR7Ym1hdHJpeH0NCiAgICAgIFxiZWdpbntibWF0cml4fQ0KICAgICAgICBhXFwNCiAgICAgICAgYg0KICAgICAgXGVuZHtibWF0cml4fQ0KJCQNCg0KRXhwYW5kIHRoZSBhYm92ZSBtYXRyaXggdG8gZ2V0IHRoZSBxdWFkcmF0aWMgZm9ybSANCg0KJCQNClx0ZXh0e3Zhcn0oWikgPSBhXjIgXHRleHR7dmFyfShYKSArIDJhYlx0aW1lcyBcdGV4dHtjb3Z9KFgsWSkgKyBiXjIgXHRleHR7dmFyfShZKS4NCiQkDQoNCg0KXA0KDQoNCiMjIE11bHRpdmFyaWF0ZSBOb3JtYWwgRGlzdHJpYnV0aW9uDQoNClJlY2FsbCB0aGUgZGVuc2l0eSBmdW5jdGlvbiBvZiB1bml2YXJpYXRlIHJhbmRvbSB2YXJpYWJsZSAkWCQgd2l0aCBtZWFuICRcbXUkIGFuZCB2YXJpYW5jZSAkXHNpZ21hXjIkIGlzIGdpdmVuIGJ5DQoNCiQkDQpmKHgpID0gXGZyYWN7MX17XHNxcnR7MlxwaX1cc2lnbWF9ZV57LVxmcmFjeyh4LVxtdSleMn17MlxzaWdtYV4yfX0sIFwgXCBcdGV4dHsgZm9yIH0gXCAtXGluZnR5IDwgeCA8IFxpbmZ0eS4NCiQkDQoNCioqRXhhbXBsZSoqOiBTdXBwb3NlICRYJCBpcyB0aGUgaGVpZ2h0IChpbiBpbmNoZXMpIGFuZCAkWSQgaXMgdGhlIHdlaWdodCAoaW4gcG91bmRzKSBvZiBhIG1hbGUgc3R1ZGVudCBpbiBhIGxhcmdlIHVuaXZlcnNpdHkuIEZ1cnRoZXJtb3JlIHN1cHBvc2UgdGhhdCAkWCQgYW5kICRZJCBmb2xsb3cgbm9ybWFsIGRpc3RyaWJ1dGlvbiB3aXRoIHBhcmFtZXRlcnMgJFxtdV9YPTY5JCwgJFxtdV9ZPTE1NSQsICRcc2lnbWFfWD0yLjUkLCBhbmQgJFxzaWdtYV9ZPTIwJC4gRnVydGhlcm1vcmUsIHRoZSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCBiZXR3ZWVuICRYJCBhbmQgJFkkIGlzICRccmhvPTAuNTUkLiBUaGVyZSBtYXkgYmUgZGlmZmVyZW50IGRpc3RyaWJ1dGlvbnMgdGhhdCBzYXRpc2Z5IHRoZSBnaXZlbiBjb25kaXRpb25zLiBIb3dldmVyLCB0aGUgZ2l2ZW4gY29uZGl0aW9ucyB1bmlxdWVseSBkZXRlcm1pbmUgdGhlIGJpdmFyaWF0ZSBub3JtYWwgZGlzdHJpYnV0aW9uIHRoYXQgaGFzIHRoZSBmb2xsb3dpbmcgam9pbnQgZGVuc2l0eSBmdW5jdGlvbg0KDQokJA0KZih4LHkpPVxmcmFjezF9ezJccGlcc2lnbWFfeFxzaWdtYV95XHNxcnR7MS1ccmhvXjJ9fVxleHBcbGVmdFx7LVxmcmFjezF9ezIoMS1ccmhvXjIpfSBcbGVmdFsgXGxlZnQoXGZyYWN7eC1cbXVfeH17XHNpZ21hX3h9IFxyaWdodCleMiArIFxsZWZ0KFxmcmFje3ktXG11X3l9e1xzaWdtYV95fSBccmlnaHQpXjIgLVxyaG9cbGVmdChcZnJhY3t4LVxtdV94fXtcc2lnbWFfeH0gXHJpZ2h0KVxsZWZ0KFxmcmFje3ktXG11X3l9e1xzaWdtYV95fSBccmlnaHQpIFxyaWdodF0gXHJpZ2h0XH0uDQokJA0KDQpPYnZpb3VzbHksIHRoZSBkZW5zaXR5IGZvciB0aGUgQml2YXJpYXRlIE5vcm1hbCBpcyB1Z2x5LCBhbmQgaXQgb25seSBnZXRzIHdvcnNlIHdoZW4gd2UgY29uc2lkZXIgaGlnaGVyIGRpbWVuc2lvbmFsIGpvaW50IGRlbnNpdGllcyBvZiBtb3JlIG5vcm1hbCBkaXN0cmlidXRpb25zLiBXZSBjYW4gd3JpdGUgdGhlIGRlbnNpdHkgaW4gYSBtb3JlIGNvbXBhY3QgZm9ybSB1c2luZyBtYXRyaXggbm90YXRpb24sDQoNCkRlbm90ZQ0KDQokJA0KXG1hdGhiZnt4fSA9IFxiZWdpbntibWF0cml4fQ0KICAgICAgICAgICAgIHggXFwNCiAgICAgICAgICAgICB5DQogICAgICAgICAgICAgXGVuZHtibWF0cml4fSwgXCBcIFwgXA0KXG11ID0gXGJlZ2lue2JtYXRyaXh9DQogICAgICAgICAgICAgXG11X3ggXFwNCiAgICAgICAgICAgICBcbXVfeQ0KICAgICAgICAgICAgIFxlbmR7Ym1hdHJpeH0gXCBcIFwgXA0KXG1hdGhiZntcU2lnbWF9ID0gXGJlZ2lue2JtYXRyaXh9DQogICAgICAgICAgICAgXHNpZ21hX3heMiAmIFxyaG9cc2lnbWFfeFxzaWdtYV95IFxcDQogICAgICAgICAgICAgXHJob1xzaWdtYV94XHNpZ21hX3kgJiBcc2lnbWFfeV4yIA0KICAgICAgICAgICAgIFxlbmR7Ym1hdHJpeH0gXCBcIFwgXA0KJCQNCg0KVGhlIG1hdHJpeCBmb3JtIG9mIHRoZSBiaXZhcmlhdGUgbm9ybWFsIGRpc3RyaWJ1dGlvbiBpcyBnaXZlbiBieQ0KDQokJA0KZihcbWF0aGJme3h9KSA9IFxmcmFjezF9ezJccGl9IChcdGV4dHtkZXR9XG1hdGhiZntcU2lnbWF9KV57LTEvMn1cZXhwXGxlZnRbLVxmcmFjezF9ezJ9KFxtYXRoYmZ7eH0tXG11KV5UIFxtYXRoYmZ7XFNpZ21hfV57LTF9KFxtYXRoYmZ7eH0tXG11KVxyaWdodF0uDQokJA0KDQokXFNpZ21hJCBpcyB0aGUgY292YXJpYW5jZSBtYXRyaXggb2YgJFxtYXRoYmZ7eH0kLiBUaGUgYWJvdmUgZXhwcmVzc2lvbiBjYW4gYmUgZ2VuZXJhbGl6ZWQgdG8gbXVsdGl2YXJpYXRlIG5vcm1hbCBkaXN0cmlidXRpb24uIFRoZSBtdWx0aXZhcmlhdGUgbm9ybWFsIGRpc3RyaWJ1dGlvbiBpcyB1bmlxdWVseSBkZXRlcm1pbmVkIGlmIHRoZSBjb3ZhcmlhbmNlIG1hdHJpeCBpcyBzcGVjaWZpZWQuDQoNCg0KPGZvbnQgY29sb3IgPSAicmVkIj4qXGNvbG9ye3JlZH1XaXRoIHRoZSBhYm92ZSBleGFtcGxlKjwvZm9udD4sIHdlIGNhbiBzcGVjaWZ5IHRoZSB2ZWN0b3IgYW5kIGNvdmFyaWFuY2UgbWF0cml4IHJlcXVpcmVkIGluIHRoZSBiaXZhcmlhdGUgbm9ybWFsIGRpc3RyaWJ1dGlvbi4NCg0KJCQNClxtdSA9IFxiZWdpbntibWF0cml4fQ0KICAgICAgIDY5IFxcDQogICAgICAgMTU1DQogICAgICBcZW5ke2JtYXRyaXh9IFwgXCBcdGV4dHsgYW5kIH0gXCBcDQpcbWF0aGJme1xTaWdtYX0gPSBcYmVnaW57Ym1hdHJpeH0NCiAgICAgICAyLjVeMiAgJiAgMC41NVx0aW1lcyAyLjUgXHRpbWVzIDIwXFwNCiAgICAgICAwLjU1XHRpbWVzIDIuNSBcdGltZXMgMjAwICAgJiAyMF4yDQogICAgICBcZW5ke2JtYXRyaXh9ID0gDQogICAgICBcYmVnaW57Ym1hdHJpeH0NCiAgICAgICA2LjI1ICAmICAyNy41XFwNCiAgICAgICAyNy41ICAmIDQwMA0KICAgICAgIFxlbmR7Ym1hdHJpeH0NCiQkDQoNCiQkDQpcdGV4dHtkZXR9XG1hdGhiZntcU2lnbWF9ID0gNi4yNVx0aW1lcyA0MDAgLSAyNy41XjIgPSAxNzQzLjc1Lg0KJCQNCmFuZA0KDQokJA0KXG1hdGhiZntcU2lnbWF9XnstMX0gPSBcZnJhY3sxfXs2LjI1XHRpbWVzIDQwMCAtIDI3LjVeMn1cYmVnaW57Ym1hdHJpeH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDQwMCAgICYgLTI3LjUgXFwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0yNy41ICYgNi4yNQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcZW5ke2JtYXRyaXh9DQogICAgICAgICAgICAgICAgICAgICA9IFxiZWdpbntibWF0cml4fQ0KICAgICAgICAgICAgICAgICAgICAgICAgMC4yMjkzOTA3ICAmICAtMC4wMTU3NzA2MSBcXA0KICAgICAgICAgICAgICAgICAgICAgICAgLTAuMDE1NzcwNjEgJiAwLjAwMzU4NDIyOQ0KICAgICAgICAgICAgICAgICAgICAgICBcZW5ke2JtYXRyaXh9Lg0KJCQNCg0KJCQNCmYoXG1hdGhiZnt4fSkgPSAwLjAwMzhcZXhwIFxsZWZ0Wy1cZnJhY3sxfXsyfSh4LTY5LCB5LTE1NSkgXGJlZ2lue2JtYXRyaXh9DQogICAgICAgICAgICAgICAgICAgICAgICAwLjIyOTQgICYgIC0wLjAxNTggXFwNCiAgICAgICAgICAgICAgICAgICAgICAgIC0wLjAxNTggJiAwLjAwMzYNCiAgICAgICAgICAgICAgICAgICAgICAgXGVuZHtibWF0cml4fSANCiAgICAgICAgICAgICAgICAgICAgICAgXGJlZ2lue2JtYXRyaXh9DQogICAgICAgICAgICAgICAgICAgICAgICB4LTY5IFxcDQogICAgICAgICAgICAgICAgICAgICAgICB5LTE1NSANCiAgICAgICAgICAgICAgICAgICAgICAgXGVuZHtibWF0cml4fSANCiAgICAgICAgICAgICAgICAgICAgICAgXHJpZ2h0XS4NCiQkDQoNCioqTm90YXRpb24gb2YgR2VuZXJhbCBNdWx0aXZhcmlhdGUgTm9ybWFsIERpc3RyaWJ1dGlvbioqDQoNCkxldCANCg0KJCQNClxtYXRoYmZ7WH0gPSBcYmVnaW57cG1hdHJpeH0NClhfMSBcXA0KWF8yIFxcDQpcdmRvdHMgXFwNClhfaw0KXGVuZHtwbWF0cml4fSwgXCBcIFwNClxtYXRoYmZ7XG11fSA9IFxiZWdpbntwbWF0cml4fQ0KXG11XzEgXFwNClxtdV8yIFxcDQpcdmRvdHMgXFwNClxtdV9rDQpcZW5ke3BtYXRyaXh9LCBcIFwgXHRleHR7IGFuZCB9IFwgXA0KXG1hdGhiZntcU2lnbWF9ID0gXGJlZ2lue3BtYXRyaXh9DQpcc2lnbWFfMV4yICYgXHNpZ21hX3sxMn0gJiBcc2lnbWFfezEzfSAmIFxjZG90cyAmIFxzaWdtYV97MWt9ICBcXA0KXHNpZ21hX3syMX0gJiBcc2lnbWFfMl4yICYgXHNpZ21hX3syM30gJiBcY2RvdHMgJiBcc2lnbWFfezJrfSAgXFwNClx2ZG90cyAmIFx2ZG90cyAgJiBcdmRvdHMgJiBcdmRvdHMgICYgXHZkb3RzIFxcDQpcc2lnbWFfe2sxfSAmIFxzaWdtYV97azJ9ICYgXHNpZ21hX3trM30gJiBcY2RvdHMgJiBcc2lnbWFfe2trfSANClxlbmR7cG1hdHJpeH0uDQokJA0KDQpXZSB1c2UgdGhlIGZvbGxvd2luZyBub3RhdGlvbiB0byBkZW5vdGUgdGhlIGstZGltZW5zaW9uYWwgbm9ybWFsIGRpc3RyaWJ1dGlvbg0KDQokJA0KXG1hdGhiZntYfSBcc2ltICBcbWF0aGNhbHtOfV9rKFxtdSwgXG1hdGhiZntcU2lnbWF9KS4NCiQkDQoNCjxmb250IGNvbG9yID0gInJlZCI+KipcY29sb3J7cmVkfVByb3BlcnRpZXMgb2YgTXVsdGl2YXJpYXRlIE5vcm1hbCBEaXN0cmlidXRpb25zKio8L2ZvbnQ+IA0KDQpMZXQgJFxtYXRoYmZ7WH0gPSBbWF8xLCBYXzIsIFxjZG90cywgWF9rXV5UJCBhbmQgJFxtdSA9IEVbXG1hdGhiZntYfV0kLCBhbmQgJFx0ZXh0e2Nvdn0oXG1hdGhiZntYfSkgPSBcbWF0aGJme1xTaWdtYX0gPSAoXHNpZ21hX3tpan0pJC4gVGhlIG11bHRpdmFyaWF0ZSBub3JtYWwgZGlzdHJpYnV0aW9uIGlzIGdpdmVuIGJ5DQoNCiQkDQpcbWF0aGJme1h9IFxyaWdodGFycm93X3AgXG1hdGhjYWx7Tn1fayhcbXUsIFxtYXRoYmZ7XFNpZ21hfSkuDQokJA0KDQpUaGUgZm9sbG93aW5nIGFyZSBwcm9wZXJ0aWVzIG9mIG11bHRpdmFyaWF0ZSBub3JtYWwgZGlzdHJpYnV0aW9ucyB0aGF0IHdpbGwgYmUgdXNlZCBpbiB0aGUgc3Vic2VxdWVudCBub3RlLg0KDQoxLiBBbGwgKiptYXJnaW5hbCBkaXN0cmlidXRpb25zKiogPGZvbnQgY29sb3IgPSAiYmx1ZSI+Klxjb2xvcntibHVlfShkaXN0cmlidXRpb24gb2YgaW5kaXZpZHVhbCBjb21wb25lbnQgb2YgbXVsdGl2YXJpYXRlIG5vcm1hbCkqPC9mb250PiBvZiBhIG11bHRpdmFyaWF0ZSBub3JtYWwgZGlzdHJpYnV0aW9uIGFyZSAqKm5vcm1hbCBkaXN0cmlidXRpb25zKiouDQoNCjIuIEFsbCAqKmNvbmRpdGlvbmFsIGRpc3RyaWJ1dGlvbnMqKiBvZiBhIG11bHRpdmFyaWF0ZSBub3JtYWwgZGlzdHJpYnV0aW9uIGFyZSAqKm5vcm1hbCBkaXN0cmlidXRpb24qKi4NCg0KMy4gQWxsICoqbGluZWFyIGNvbWJpbmF0aW9ucyBvZiB0aGUgY29tcG9uZW50cyoqIG9mIG11bHRpdmFyaWF0ZSBub3JtYWwgZGlzdHJpYnV0aW9uIGFyZSBhbHNvICoqbm9ybWFsIGRpc3RyaWJ1dGlvbnMqKi4NCg0KXA0KDQojIyBBc3ltcHRvdGljIE5vcm1hbGl0eSBvZiBNTEUNCg0KUmVjYWxsIHRoZSBNTEUgb2YgJFxtYXRoYmZ7XHRoZXRhfSQgYmFzZWQgb24gSUlEICRce3hfMSwgeF8yLCBcY2RvdHMsIHhfbiBcfSBcc3RhY2tyZWx7XHRleHR7aWlkfX17XHNpbX0gZih4Olx0aGV0YSkkLCBkZW5vdGVkIGJ5ICRcaGF0e1x0aGV0YX0kLCBpcyB0aGUgc29sdXRpb24gdG8gdGhlIGZvbGxvd2luZyBvcHRpbWl6YXRpb24gcHJvYmxlbQ0KDQokJA0KXGhhdHtcbWF0aGJme1x0aGV0YX19ID0gXGFyZ1xtaW5fe1x0aGV0YSBcaW4gXFRoZXRhfSBcbG9nIEwoXHRoZXRhOiBcbWF0aGJme3h9KQ0KJCQNCg0Kd2hlcmUgJEwoXHRoZXRhKSQgaXMgdGhlIGxpa2VsaWhvb2Qgb2YgJFx0aGV0YSQgdGhhdCBnaXZlbiBleHBsaWNpdGx5IGluIHRoZSBmb2xsb3dpbmcNCg0KJCQNCkwoXHRoZXRhOiBcbWF0aGJme3h9KSA9IFxwcm9kX3tpPTF9Xm4gZih4X2k6XHRoZXRhKS4NCiQkDQoNClRoZSAqKkZpc2hlciBJbmZvcm1hdGlvbioqIG9mICRcdGhldGEkIGlzIGdpdmVuIGJ5DQoNCiQkDQpcbWF0aGJie0l9X24oXHRoZXRhKSA9IEVcbGVmdFsgXGxlZnQoXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFx0aGV0YX0gXGxvZyBMKFx0aGV0YTpcbWF0aGJme3h9KVxyaWdodCkgXGxlZnQoIFxmcmFje1xwYXJ0aWFsfXtccGFydGlhbCBcdGhldGF9IFxsb2cgTChcdGhldGE6XG1hdGhiZnt4fSkgXHJpZ2h0KV5UXHJpZ2h0XQ0KJCQNCg0KJCQNCj0gLSBFXGxlZnRbIFxmcmFje1xwYXJ0aWFsXjJ9e1xwYXJ0aWFsIFx0aGV0YSBccGFydGlhbCBcdGhldGFeVH0gXGxvZyBMKFx0aGV0YTpcbWF0aGJme3h9KVxyaWdodF0uDQokJA0KDQpEZW5vdGUgdGhlICoqRmlzaGVyIEluZm9ybWF0aW9uIE1hdHJpeCoqIGJhc2VkIG9uIGluZGl2aWR1YWwgb2JzZXJ2ZWQgZGF0YSBwb2ludHMgYnkgDQoNCiQkDQpcbWF0aGJie0l9XzAoXHRoZXRhKSA9LSBFXGxlZnRbIFxmcmFje1xwYXJ0aWFsXjJ9e1xwYXJ0aWFsIFx0aGV0YSBccGFydGlhbCBcdGhldGFeVH0gXGxvZyBMKFx0aGV0YTp4KVxyaWdodF0gPSBcZnJhY3tcbWF0aGJie0l9X24oXHRoZXRhKX17bn0uDQokJA0KDQpXaXRoIHRoZSBhYm92ZSBkaXNjdXNzaW9ucyBhbmQgbm90YXRpb25zLCB3ZSBoYXZlIHRoZSBmb2xsb3dpbmcgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIE1MRSBvZiAkXHRoZXRhJC4NCg0KDQoqKlRoZW9yZW0qKjogKCpBc3ltcHRvdGljIG5vcm1hbGl0eSBvZiBNTEUqKSBVbmRlciBzb21lIHJlZ3VsYXJpdHkgY29uZGl0aW9ucywgdGhlIE1MRSBvZiAkXHRoZXRhJCBiYXNlZCBvbiAkXHt4XzEsIHhfMiwgXGNkb3RzLCB4X24gXH1cc3RhY2tyZWx7XHRleHR7aWlkfX17XHNpbX0gZih4Olx0aGV0YSkkIGhhcyB0aGUgZm9sbG93aW5nIGFzeW1wdG90aWMgbm9ybWFsaXR5DQoNCiQkDQpcc3FydHtufShcaGF0e1x0aGV0YX0gLSBcdGhldGEpIFxzdGFja3JlbHtcdGV4dHthcHByb3h9fXtccmlnaHRhcnJvd19wfSBcbWF0aGNhbHtOfVxsZWZ0W1xtYXRoYmZ7MH0sIFxtYXRoYmJ7SX1fMF57LTF9KFx0aGV0YSlccmlnaHRdLg0KJCQNCg0KU2luY2UgJFx0aGV0YSQgaW4gdGhlIGNvdmFyaWFuY2UgbWF0cml4ICRcbWF0aGJie0l9XzBeey0xfSQgaXMgdW5rbm93bi4gV2hlbiBtYWtpbmcgaW5mZXJlbmNlcywgd2UgdXNlICRcd2lkZWhhdHtcbWF0aGJie0l9XzAoXHRoZXRhKX0gPSBcbWF0aGJie0l9XzAoXGhhdHtcdGhldGF9KSQuDQoNCjxmb250IGNvbG9yID0gInJlZCI+KipcY29sb3J7cmVkfVJlbWFya3MqKjo8L2ZvbnQ+DQoNCjEuICRcc3FydHtufShcaGF0e1x0aGV0YX0gLSBcdGhldGEpJCBpcyBhcHByb3hpbWF0ZWx5IG5vcm1hbGx5IGRpc3RyaWJ1dGVkIHdoZW4gdGhlIHNhbXBsZSBzaXplIGlzIGxhcmdlLiBUaGUgdmFyaWFuY2Ugb2YgJFxzcXJ0e259KFxoYXR7XHRoZXRhfSAtIFx0aGV0YSkkIGlzICRcbWF0aGJie0l9XzBeey0xfShcdGhldGEpJCB3aGljaCBpcyBpbmRlcGVuZGVudCBvZiB0aGUgc2FtcGxlIHNpemUgYW5kIGlzIGRlZmluZWQgYmFzZWQgb24gdGhlIGluZGl2aWR1YWwgcmFuZG9tIGRhdGEgcG9pbnQuDQoNCjIuICRcdGhldGEkIGlzIHRoZSB1bmtub3duIHBhcmFtZXRlciBhbmQgJFxoYXR7XHRoZXRhfSQgaXMgdGhlIE1MRSBvZiAkXHRoZXRhJC4NCg0KMy4gJFxzcXJ0e259KFxoYXR7XHRoZXRhfSAtIFx0aGV0YSkkIGNhbiBiZSBjb25zaWRlcmVkIGFzIGEgc2VxdWVuY2Ugb2YgcmFuZG9tIHZhcmlhYmxlcyAoaW5kZXhlZCBieSB0aGUgc2FtcGxlIHNpemUgJG4kKS4gJFxyaWdodGFycm93X3AkIHN0YW5kcyBmb3IgKipjb252ZXJnZXMgaW4gZGlzdHJpYnV0aW9uKiouDQoNCg0KXA0KDQoqKkV4YW1wbGUqKjogVGhlIGZvbGxvd2luZyBkYXRhIHJlcHJlc2VudCBhY3RpdmUgcmVwYWlyIHRpbWVzIChpbiBob3VycykgZm9yIGFuIGFpcmJvcm5lIGNvbW11bmljYXRpb24gdHJhbnNjZWl2ZXIuDQoNCjAuMiwgMC4zLCAwLjUsIDAuNSwgMC41LCAwLjUsIDAuNiwgMC42LCAwLjcsIDAuNywgMC43LCAwLjgsIDAuOCwgMS4wLCAxLjAsIDEuMCwgMS4wLCAxLjEsIDEuMywgMS41LCAxLjUsDQoxLjUsIDEuNSwgMi4wLCAyLjAsIDIuMiwgMi41LCAzLjAsIDMuMCwgMy4zLCAzLjMsIDQuMCwgNC4wLCA0LjUsIDQuNywgNS4wLCA1LjQsIDUuNCwgNy4wLCA3LjUsIDguOCwgOS4wLA0KMTAuMywgMjIuMCwgMjQuNS4NCg0KQXNzdW1pbmcgdGhlIGFib3ZlIGRhdGEgc2V0IHdhcyB0YWtlbiBmcm9tIGEgV2VpYnVsbCBkaXN0cmlidXRpb24gd2l0aCBkZW5zaXR5IGZ1bmN0aW9uICRmKHgsIFxhbHBoYSwgXGJldGEpID0gXGFscGhhXGJldGEgeF57XGJldGEtMX0gZV57LVxhbHBoYSB4XlxiZXRhfSQuDQoNCkFzIHdlIGRlcml2ZWQgaW4gdGhlIHByZXZpb3VzIG5vdGUsIHRoZSBsb2ctbGlrZWxpaG9vZCBvZiBvYnNlcnZpbmcgdGhlIGRhdGEgaXMgYSBmdW5jdGlvbiBvZiAkXGFscGhhJCBhbmQgJFxiZXRhJA0KDQokJA0KbChcYWxwaGEsIFxiZXRhKSA9IG5bXGxvZyhcYWxwaGEpICsgXGxvZyAoXGJldGEpXSArIChcYmV0YSAtMSlcc3VtX3tpPTF9Xm5cbG9nICh4X2kpLVxhbHBoYVxzdW1fe2k9MX1ebiB4X2leXGJldGENCiQkDQoNCmBgYHtyfQ0KbGlicmFyeShwbG90bHkpDQojIERhdGEgc2V0DQpkYXQgPSBjKDAuMiwgMC4zLCAwLjUsIDAuNSwgMC41LCAwLjUsIDAuNiwgMC42LCAwLjcsIDAuNywgMC43LCAwLjgsIDAuOCwgMS4wLCAxLjAsIA0KICAgICAgICAxLjAsIDEuMCwgMS4xLCAxLjMsIDEuNSwgMS41LCAxLjUsIDEuNSwgMi4wLCAyLjAsIDIuMiwgMi41LCAzLjAsIDMuMCwgMy4zLCANCiAgICAgICAgMy4zLCA0LjAsIDQuMCwgNC41LCA0LjcsIDUuMCwgNS40LCA1LjQsIDcuMCwgNy41LCA4LjgsIDkuMCwgMTAuMywgMjIuMCwgMjQuNSkNCm4gPSBsZW5ndGgoZGF0KQ0KeDEgPSBzZXEoMC4xLCAwLjUsIGxlbmd0aCA9IDUwKQ0KeTEgPSBzZXEoMC4xLCAxLCBsZW5ndGggPSA1MCkNCiMjIGxvZy1saWtlbGlob29kDQp6ZnVuIDwtIGZ1bmN0aW9uKHgxLHkxKXsNCiAgZXhwKG4qbG9nKHgxKSArIG4qbG9nKHkxKSArICh5MS0xKSpzdW0obG9nKGRhdCkpIC0geDEqc3VtKGRhdF55MSkpDQp9DQp6ID0gb3V0ZXIoeDEsIHkxLCB6ZnVuKQ0KcGxvdF9seSh4ID0geDEsIHkgPSB5MSwgeiA9IHopICU+JSBhZGRfc3VyZmFjZSgpDQpgYGANCg0KDQoNCg0KVGhlIHNjb3JlIGVxdWF0aW9ucyBhcmUgZ2l2ZW4gYnkNCg0KJCQNClxiZWdpbntjYXNlc30gDQpcZnJhY3tccGFydGlhbCBsKFxhbHBoYSwgXGJldGEpfXtccGFydGlhbCBcYWxwaGF9ID0gXGZyYWN7bn17XGFscGhhfSAtIFxzdW1fe2k9MX1ebiB4X2leXGJldGE9IDAgLCAgICBcXCANClxmcmFje1xwYXJ0aWFsIGwoXGFscGhhLCBcYmV0YSl9e1xwYXJ0aWFsIFxiZXRhfT0gXGZyYWN7bn17XGJldGF9ICsgXHN1bV97aT0xfV5uIFxsb2coeF9pKSAtIFxhbHBoYSBcc3VtX3tpPTF9Xm4geF9pXlxiZXRhIFxsb2coeF9pKT0gMC4NClxlbmR7Y2FzZXN9IA0KJCQNCg0KV2UgbmV4dCB3cml0ZSBSIGNvZGUgdG8gZmluZCB0aGUgTUxFIGFuZCB0aGUgSGVzc2lhbiBtYXRyaXggKHRoZSBuZWdhdGl2ZSBvYnNlcnZlZCBGaXNoZXIgSW5mb3JtYXRpb24gTWF0cml4KS4NCg0KDQpgYGB7cn0NCiMgRGF0YSBzZXQNCnggPSBjKDAuMiwgMC4zLCAwLjUsIDAuNSwgMC41LCAwLjUsIDAuNiwgMC42LCAwLjcsIDAuNywgMC43LCAwLjgsIDAuOCwgMS4wLCAxLjAsIDEuMCwgMS4wLCANCiAgICAgIDEuMSwgMS4zLCAxLjUsIDEuNSwgMS41LCAxLjUsIDIuMCwgMi4wLCAyLjIsIDIuNSwgMy4wLCAzLjAsIDMuMywgMy4zLCA0LjAsIDQuMCwgNC41LCANCiAgICAgIDQuNywgNS4wLCA1LjQsIDUuNCwgNy4wLCA3LjUsIDguOCwgOS4wLCAxMC4zLCAyMi4wLCAyNC41KQ0KbiA9IGxlbmd0aCh4KQ0KIyMgbG9nLWxpa2VsaWhvb2QNCm5lZ0xvZ0xpayA9IGZ1bmN0aW9uKEEpew0KICBhID0gQVsxXQ0KICBiID0gQVsyXQ0KICBuKmxvZyhhKSArIG4qbG9nKGIpICsgKGItMSkqc3VtKGxvZyh4KSkgLSBhKnN1bSh4XmIpDQp9DQojIyBncmFkaWVudCBmdW5jdGlvbg0KZ3JGdW4gPSBmdW5jdGlvbihBKXsNCiAgYSA9IEFbMV0NCiAgYiA9IEFbMl0NCiAgZ2EgPSBuL2EgLSBzdW0oeF5iKQ0KICBnYj0gbi9iICtzdW0obG9nKHgpKSAtYSpzdW0oeF5iKmxvZyh4KSkNCiAgYyhnYSxnYikNCn0NCiMjIGNhbGxpbmcgUiBmdW5jdGlvbiBvcHRpbSgpDQpyZXN1bHRzID0gb3B0aW0ocGFyID0gYyguNSwuNSksIGZuID0gbmVnTG9nTGlrLCBnciA9IGdyRnVuLCBtZXRob2QgPSAiQkZHUyIsIA0KICAgICAgY29udHJvbCA9IGxpc3QobWF4aXQgPSAyMDAwMCxmbnNjYWxlID0gLTEpLCBoZXNzaWFuID0gVFJVRSkNCk1MRSA9IHJlc3VsdHMkcGFyDQpDb3VudHMgPSByZXN1bHRzJGNvdW50cw0KQ29udmVyZ2VuY2UgPSByZXN1bHRzJGNvbnZlcmdlbmNlDQpIZXNzaWFuID0gcmVzdWx0cyRoZXNzaWFuDQpJMC5pbnYgPSAtc29sdmUoSGVzc2lhbi9uKQ0Kb3V0ID0gbGlzdChNTEUgPSBNTEUsIENvdW50cyA9IENvdW50cywgQ29udmVyZ2VuY2UgPSBDb252ZXJnZW5jZSwgSGVzc2lhbiA9IEhlc3NpYW4sIEkwLmludiA9IEkwLmludikNCm91dA0KYGBgDQoNCmBgYHtyfQ0KZ3JGdW4oYygwLjMzNzcyNTksIDAuODg5NjE3OCkpIA0KYGBgDQoNCg0KYGBge3J9DQpuZWdMb2dMaWswID0gZnVuY3Rpb24oQSl7DQogIGEgPSBBWzFdDQogIGIgPSBBWzJdDQogIC0obipsb2coYSkgKyBuKmxvZyhiKSArIChiLTEpKnN1bShsb2coeCkpIC0gYSpzdW0oeF5iKSkNCn0NCm5sbShuZWdMb2dMaWswLCBwID0gYygxLDEpLCBoZXNzaWFuPVRSVUUpDQpgYGANCg0KDQoNCg0KVGhlcmVmb3JlLCB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mICQoXGhhdHtcYWxwaGF9LCBcaGF0e1xiZXRhfSkkIGlzIGdpdmVuIGJ5DQoNCiQkDQpcc3FydHtufVxiZWdpbntwbWF0cml4fQ0KIFxoYXR7XGFscGhhfSAtIFxhbHBoYSAgXFwNCiBcaGF0e1xiZXRhfSAtIFxiZXRhIA0KXGVuZHtwbWF0cml4fSBccmlnaHRhcnJvd19wIFxtYXRoY2Fse059IFxsZWZ0WyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcYmVnaW57cG1hdHJpeH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIFxcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxlbmR7cG1hdHJpeH0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXGJlZ2lue3BtYXRyaXh9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMC4yNjMxNzg1ICYgLTAuMjQ4NzUzMSBcXA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0wLjI0ODc1MzEgJiAwLjQxNDk1NTINCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcZW5ke3BtYXRyaXh9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXHJpZ2h0XQ0KJCQNCg0KPGZvbnQgY29sb3IgPSAicmVkIj4qKlxjb2xvcntyZWR9UmVtYXJrcyoqPC9mb250Pg0KDQoxLiA8Zm9udCBjb2xvciA9ICJibHVlIj4qKlxjb2xvcntibHVlfUNhdXRpb246ICoqPC9mb250PiA8Zm9udCBjb2xvciA9ICJyZWQiPipcY29sb3J7cmVkfVRoZSAgSGVzc2lhbiBtYXRyaXggJFxtYXRoYmJ7SH0kIHJlcG9ydGVkIGluIGBvcHRpbSgpYCBpcyBuZWdhdGl2ZSBvYnNlcnZlZCBGaXNoZXIgaW5mb3JtYXRpb246ICQtXHdpZGVoYXR7XG1hdGhiYntJfV9uKFx0aGV0YSl9ID0gLVxtYXRoYmJ7SX1fbihcaGF0e1x0aGV0YX0pJCEqPC9mb250Pg0KDQoyLiBUaGUgY292YXJpYW5jZSBtYXRyaXggaW4gdGhlIGFzeW1wdG90aWMgbm9ybWFsaXR5IG9mIE1MRSByZXF1aXJlcyAkXG1hdGhiYntJfV8wKFx0aGV0YSkkLiBUaGUgb2JzZXJ2ZWQgRmlzaGVyIGluZm9ybWF0aW9uICRcbWF0aGJie1xoYXR7XHRoZXRhfX0kIGlzIGVxdWFsIHRvIHRoZSBIZXNzaWFuIG1hdHJpeCwgJFxtYXRoYmJ7SH1fbiQsIGRpdmlkZWQgYnkgc2FtcGxlIHNpemUgJG4kLiBUaGF0IGlzLCAkXG1hdGhiYntJfV8wKFxoYXR7XHRoZXRhfSkgPSAtXG1hdGhiYntIKFx0aGV0YTpcbWF0aGJme3h9KX0vbi4kDQoNCjMuICRcdGV4dHt2YXJ9W1xzcXJ0e259KFxoYXR7XGFscGhhfSktXGFscGhhXSA9IG5cdGV4dHt2YXJ9KFxoYXR7XGFscGhhfSkgPSAwLjI2MzE3ODUkIHdoaWNoIGltcGxpZXMgdGhhdCAkXHRleHR7dmFyfShcaGF0e1xhbHBoYX0pID0gMC4yNjMxNzg1LzQ1IFxhcHByb3ggMC4wMDU4NDg0MTEkOyAkXHRleHR7dmFyfVtcc3FydHtufShcaGF0e1xiZXRhfSktXGJldGFdID0gblx0ZXh0e3Zhcn0oXGhhdHtcYmV0YX0pID0gMC40MTQ5NTUyJCB3aGljaCBpbXBsaWVzIHRoYXQgJFx0ZXh0e3Zhcn0oXGhhdHtcYmV0YX0pID0gMC40MTQ5NTUyLzQ1IFxhcHByb3ggIDAuMDA5MjIxMjI3JDsgYW5kICRcdGV4dHtjb3Z9KFxoYXR7XGFscGhhfSwgXGhhdHtcYmV0YX0pID0gLTAuMjQ4NzUzMS80NSA9IC0wLjAwNTUyNzg0NyQuDQoNCg0KNC4gTGV0ICRcaGF0e1xvbWVnYX0gPSBjXGhhdHtcYWxwaGF9ICsgZFxoYXR7XGJldGF9JC4gVGhlbiAkXHRleHR7dmFyfShcaGF0e1xvbWVnYX0pID0gXHRleHR7dmFyfVsgY1xoYXR7XGFscGhhfSArIGRcaGF0e1xiZXRhfV0gPSBjXjJcdGV4dHt2YXJ9KFxoYXR7XGFscGhhfSkgKyBkXjJcdGV4dHt2YXJ9KFxoYXR7XGJldGF9KSArIDJjZFx0ZXh0e2Nvdn0oXGhhdHtcYWxwaGF9LCBcaGF0e1xiZXRhfSkgPSAwLjAwNTg0ODQxMWNeMiArIDAuMDA5MjIxMjI3ZF4yIC0gMlx0aW1lcyAwLjAwNTUyNzg0N2NkJC4NCg0KXA0KDQoNCg0KIyBJbmZlcmVuY2Ugb2YgTUxFDQoNClRocmVlIHR5cGVzIG9mIGluZmVyZW5jZXMgd2lsbCBiZSBkaXNjdXNzZWQgaW4gdGhpcyBzZWN0aW9uOiBjb25maWRlbmNlIGludGVydmFscywgYW5kIHNpZ25pZmljYW5jZSB0ZXN0cy4NCg0KIyMgQ29uZmlkZW5jZSBJbnRlcnZhbHMNCg0KQmVjYXVzZSBNTEVzIGFyZSBhc3ltcHRvdGljYWxseSBub3JtYWxseSBkaXN0cmlidXRlZCwgd2UgY2FuIHVzZSB0aGUgc2FtZSBwcm9jZWR1cmUgYXMgd2UgdXNlZCBpbiBpbnRyb2R1Y3Rvcnkgc3RhdGlzdGljcy4gQXNzdW1pbmcgdGhlIGNvbmZpZGVuY2UgbGV2ZWwgaW4gdGhlIHN1YnNlcXVlbnQgZGlzY3Vzc2lvbiBpcyAkOTVcJSQuIA0KDQpGb3IgY29udmVuaWVuY2UsIGxldCAkKFxoYXR7XHRoZXRhfV8xLCBcaGF0e1x0aGV0YX1fMikkIGJlIHRoZSBNTEUgb2YgJChcdGhldGFfMSwgXHRoZXRhXzIpJCBiYXNlZCBvbiBhbiBJSUQgc2FtcGxlICRce3hfMSwgeF8yLCBcY2RvdHMsIHhfbiBcfSBcc3RhY2tyZWx7XHRleHR7aS5pLmR9fXtcc2ltfSBmKHgsIFx0aGV0YV8xLCBcdGhldGFfMikkLiBUaGUgYXN5bXB0b3RpYyBzYW1wbGluZyBkaXN0cmlidXRpb24gb2YgdGhlIE1MRSBpcyBhc3N1bWVkIHRvIGJlDQoNCiQkDQpcc3FydHtufQ0KXGJlZ2lue3BtYXRyaXh9DQogICBcaGF0e1x0aGV0YX1fMSAtIFx0aGV0YV8xIFxcDQogICBcaGF0e1x0aGV0YX1fMiAtIFx0aGV0YV8yDQpcZW5ke3BtYXRyaXh9IFxzdGFja3JlbHtcdGV4dHthcHByb3h9fXtccmlnaHRhcnJvd19wfQ0KXG1hdGhjYWx7Tn1fMg0KXGxlZnRbDQogICAgIFxiZWdpbntwbWF0cml4fQ0KICAgICAgMCBcXA0KICAgICAgMA0KICAgICBcZW5ke3BtYXRyaXh9LA0KICAgICBcYmVnaW57cG1hdHJpeH0NCiAgICAgIFxzaWdtYV8xXjIgICYgXHNpZ21hX3sxMn0gXFwNCiAgICAgIFxzaWdtYV97MTJ9ICYgXHNpZ21hXzJeMg0KICAgICBcZW5ke3BtYXRyaXh9DQpccmlnaHRdLA0KJCQNCndoaWNoIGNhbiBiZSByZS1leHByZXNzZWQgaW4gdGhlIGZvbGxvd2luZyBmb3JtDQoNCiQkDQpcYmVnaW57cG1hdHJpeH0NCiAgIFxoYXR7XHRoZXRhfV8xICAgXFwNCiAgIFxoYXR7XHRoZXRhfV8yIA0KXGVuZHtwbWF0cml4fSBcc3RhY2tyZWx7XHRleHR7YXBwcm94fX17XHJpZ2h0YXJyb3dfcH0NClxtYXRoY2Fse059XzINClxsZWZ0Ww0KICAgICBcYmVnaW57cG1hdHJpeH0NCiAgICAgIFx0aGV0YV8xIFxcDQogICAgICBcdGhldGFfMg0KICAgICBcZW5ke3BtYXRyaXh9LA0KICAgICBcZnJhY3sxfXtufVxiZWdpbntwbWF0cml4fQ0KICAgICAgXHNpZ21hXzFeMiAgJiBcc2lnbWFfezEyfSBcXA0KICAgICAgXHNpZ21hX3sxMn0gJiBcc2lnbWFfMl4yDQogICAgIFxlbmR7cG1hdHJpeH0NClxyaWdodF0sDQokJA0Kd2hlcmUNCg0KJCQNClx0ZXh0e3Zhcn0oXGhhdHtcdGhldGF9XzEpID0gXGZyYWN7XHNpZ21hXzFeMn17bn0sIFwgXCBcdGV4dHt2YXJ9KFxoYXR7XHRoZXRhfV8yKSA9IFxmcmFje1xzaWdtYV8yXjJ9e259LCBcIFwgIFx0ZXh0eyBhbmQgfSBcIFwgXHRleHR7Y292fShcaGF0e1x0aGV0YX1fMSwgXGhhdHtcdGhldGF9XzIpID0gXGZyYWN7XHNpZ21hX3sxMn19e259Lg0KJCQNCg0KDQoNCioqRXhhbXBsZSAoY29udGludWVkKSoqOiBXZSBjYW4gcmUtZXhwcmVzcyB0aGUgYXN5bXB0b3RpYyBub3JtYWxpdHkgb2YgdGhlIE1MRSBpbiB0aGUgZXhhbXBsZSBpbiB0aGUgcHJldmlvdXMgc2VjdGlvbiBhcw0KDQokJA0KXGJlZ2lue3BtYXRyaXh9DQogICBcaGF0e1xhbHBoYX0gICBcXA0KICAgXGhhdHtcYmV0YX0gDQpcZW5ke3BtYXRyaXh9IFxzdGFja3JlbHtcdGV4dHthcHByb3h9fXtccmlnaHRhcnJvd19wfQ0KXG1hdGhjYWx7Tn1fMg0KXGxlZnRbDQogICAgIFxiZWdpbntwbWF0cml4fQ0KICAgICAgXGFscGhhIFxcDQogICAgICBcYmV0YQ0KICAgICBcZW5ke3BtYXRyaXh9LA0KICAgICBcZnJhY3sxfXs0NX1cYmVnaW57cG1hdHJpeH0NCiAgICAgICAgMC4yNjMxNzg1ICYgLTAuMjQ4NzUzMSBcXA0KICAgICAgIC0wLjI0ODc1MzEgJiAwLjQxNDk1NTINCiAgICAgXGVuZHtwbWF0cml4fQ0KXHJpZ2h0XSwNCiQkDQoNCnRoaXMgaW1wbGllcw0KDQokJA0KXHRleHR7dmFyfShcaGF0e1xhbHBoYX0pID0gXGZyYWN7MC4yNjMxNzg1fXs0NX0gPSAwLjAwNTg0ODQxMSAgXCBcIFx0ZXh0e2FuZH0gXCBcIFx0ZXh0e3Zhcn0oXGhhdHtcYmV0YX0pID0gXGZyYWN7MC40MTQ5NTUyfXs0NX0gPSAwLjAwOTIyMTIyNywNCiQkDQphbmQNCg0KJCQNClx0ZXh0e2Nvdn0oXGhhdHtcYWxwaGF9LCBcaGF0e1xiZXRhfSkgPSAtXGZyYWN7MC4yNDg3NTMxfXs0NX0gPSAwLjAwNTUyNzg0Ny4NCiQkDQpSZWNhbGwgdGhhdCB0aGUgTUxFIG9mICQoXGFscGhhLCBcYmV0YSkkIGluIHRoZSBleGFtcGxlIGFyZSAkXGhhdHtcYWxwaGF9ID0gMC4zMzc3MjcxJCBhbmQgJFxoYXR7XGJldGF9ID0gMC44ODk2MTU5JC4NCg0KDQpGb3IgY29udmVuaWVuY2UsIHdlIG9ubHkgY29uc3RydWN0ICQ5NVwlJCBjb25maWRlbmNlIGludGVydmFsIGZvciAkXHRoZXRhXzEkLg0KDQoNCiogKipUd28tc2lkZWQgY29uZmlkZW5jZSBpbnRlcnZhbCoqDQoNCiQkDQpcaGF0e1x0aGV0YV8xfSBccG0gel97MC45NzV9XGZyYWN7XGhhdHtcc2lnbWFfMX19e1xzcXJ0e259fQ0KJCQNCg0KSW4gdGhlIGFib3ZlICoqZXhhbXBsZSoqLCB0aGUgJDk1XCUkIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yICRcYWxwaGEkIGlzDQoNCiQkDQpcaGF0e1xhbHBoYX1fMSBccG0gel97MC45NzV9XHNxcnR7XGZyYWN7XGhhdHtcc2lnbWF9XzFeMn17NDV9fSA9IDAuMzM3NzI3MSBccG0gMS45NiBcdGltZXMgXHNxcnR7XGZyYWN7MC4yNjMxNzg1fXs0NX19ID0gKDAuMTg3ODM2MywgMC40ODc2MTc5KS4NCiQkDQoNCiogKipMb3dlciBhbmQgVXBwZXIgQ29uZmlkZW5jZSBJbnRlcnZhbHMqKg0KDQpUaGUgJDk1XCUkIGxvd2VyIGFuZCB1cHBlciBjb25maWRlbmNlIGludGVydmFscyBmb3IgJFxhbHBoYSQgYXJlIGdpdmVuIHJlc3BlY3RpdmVseSBieQ0KDQokJA0KXGxlZnQoLVxpbmZ0eSwgXGhhdHtcdGhldGF9XzEgKyB6X3swLjk1fVxmcmFje1xoYXR7XHNpZ21hfV8xfXtcc3FydHtufX1ccmlnaHQpIFwgXCBcdGV4dHsgYW5kIH0gXCBcIFxsZWZ0KFxoYXR7XHRoZXRhfV8xIC0gel97MC45NX1cZnJhY3tcaGF0e1xzaWdtYX1fMX17XHNxcnR7bn19LCBcaW5mdHlccmlnaHQpDQokJA0KDQoqICoqTGluZWFyIENvbmZpZGVuY2UgSW50ZXJ2YWxzKioNCg0KVGhlIGxpbmVhciBjb21iaW5hdGlvbiBvZiAkXHRoZXRhXzEkIGFuZCAkXHRoZXRhXzIkLCBkZW5vdGVkIGJ5ICRcdGhldGFfMCA9IGFcdGhldGFfMSArIGJcdGhldGFfMiQgY2FuIGJlIGVzdGltYXRlZCBieSAkXGhhdHtcdGhldGF9XzAgPSBhXGhhdHtcdGhldGF9XzEgKyBiXGhhdHtcdGhldGF9XzIkLiBCeSB0aGUgKipwbHVnaW4gUHJpbmNpcGxlIG9mIE1MRSoqLCAkXGhhdHtcdGhldGF9XzAkIGlzIGFsc28gYSBub3JtYWwgZGlzdHJpYnV0aW9uLiBUaGUgJEVbXGhhdHtcdGhldGF9XzBdID0gYUVbXGhhdHtcdGhldGF9XzFdICsgYkVbXGhhdHtcdGhldGF9XzJdID0gYVxtdV8xICsgYlxtdV8yJCwgYW5kICRcdGV4dHt2YXJ9KFxoYXR7XHRoZXRhfV8wKSA9IGFeMlxzaWdtYV8xXjIgKyBiXjJcc2lnbWFfMl4yICsgMmFiXHNpZ21hX3sxMn0kLiBUaGVuIHRoZSB0d28tc2lkZWQgJDk1XCUkIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaXMgZ2l2ZW4gYnkNCg0KJCQNClxoYXR7XHRoZXRhfV8wIFxwbSB6X3swLjk3NX1cc3FydHtcdGV4dHt2YXJ9KFxoYXR7XHRoZXRhfV8wKX0uDQokJA0KV2UgY2FuIGFsc28gY29uc3RydWN0IG9uZS1zaWRlZCBsaW5lYXIgY29uZmlkZW5jZSBpbnRlcnZhbHMgc2ltaWxhcmx5Lg0KDQpcDQoNCg0KIyMgU2lnbmlmaWNhbmNlIFRlc3RzDQoNCg0KU2lnbmlmaWNhbmNlIHRlc3RzIGFyZSBjb21tb24gaW4gcHJhY3RpY2UuIEZvciBleGFtcGxlLCBhZnRlciB3ZSBmaXQgV2VpYnVsbCBkaXN0cmlidXRpb24gJGYoeCwgXGFscGhhLCBcYmV0YSkgPSBcYWxwaGFcYmV0YSB4XntcYmV0YS0xfSBlXnstXGFscGhhIHheXGJldGF9JCB0byBhIGRhdGEgc2V0LCB3ZSBuZWVkIHRvIGFzc2VzcyB3aGV0aGVyIHRoZSBtb2RlbCB3YXMgb3ZlcmZpdHRpbmcuIElmICRcYmV0YSA9IDEkLCB0aGUgV2VpYnVsbCBkaXN0cmlidXRpb24gcmVkdWNlcyB0byBhIG9uZS1wYXJhbWV0ZXIgZXhwb25lbnRpYWwgZGlzdHJpYnV0aW9uLiBBY2NvcmRpbmcgdG8gdGhlICoqUHJpbmNpcGxlIG9mIFBhcnNpbW9ueSoqLCB3ZSBzaG91bGQgc3RheSB3aXRoIHRoZSBleHBvbmVudGlhbCBkaXN0cmlidXRpb24gb2YgdGhlIGRhdGEgc2V0LiBUZXN0aW5nIHRoZSBmb2xsb3dpbmcgaHlwb3RoZXNpcyBhZGRyZXNzZXMgdGhlIGFib3ZlIHBvdGVudGlhbCBvdmVyZml0L3VuZGVyZml0IHByb2JsZW0uDQoNCiQkDQpcbWF0aGJie0h9XzA6IFwgXCBcYmV0YSA9IDEgXCBcIFx0ZXh0eyAgdi5zLiB9IFwgXCBcbWF0aGJie0h9X2E6IFwgXCBcYmV0YSBcbmUgMS4NCiQkDQoNClRoZSBhYm92ZSB0ZXN0IGlzIGEgdHlwaWNhbCBzaWduaWZpY2FuY2UgdGVzdC4gVG8gcGVyZm9ybSB0aGUgYWJvdmUgaHlwb3RoZXNpcyB0ZXN0LCB3ZSBuZWVkIHRvIGtub3cgdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiB0aGUgTUxFIG9mICQoXGFscGhhLCBcYmV0YSkkIHdoaWNoIGlzIGFzc3VtZWQgdG8gYmUNCg0KJCQNClxiZWdpbntwbWF0cml4fQ0KICAgXGhhdHtcYWxwaGF9ICAgXFwNCiAgIFxoYXR7XGJldGF9ICAgDQpcZW5ke3BtYXRyaXh9IFxzdGFja3JlbHtcdGV4dHthcHByb3h9fXtccmlnaHRhcnJvd19wfQ0KXG1hdGhjYWx7Tn1fMg0KXGxlZnRbDQogICAgIFxiZWdpbntwbWF0cml4fQ0KICAgICAgXGFscGhhIFxcDQogICAgICBcYmV0YQ0KICAgICBcZW5ke3BtYXRyaXh9LA0KICAgICBcYmVnaW57cG1hdHJpeH0NCiAgICAgIFxzaWdtYV8xXjIvbiAgJiBcc2lnbWFfezEyfS9uIFxcDQogICAgICBcc2lnbWFfezEyfS9uICYgXHNpZ21hXzJeMi9uDQogICAgIFxlbmR7cG1hdHJpeH0NClxyaWdodF0sDQokJA0KDQpCYXNlZCBvbiB0aGUgYWJvdmUgYXN5bXB0b3RpYyBub3JtYWxpdHksIHRoZSB0ZXN0IHN0YXRpc3RpYyBmb3IgdGhlIGFib3ZlIGh5cG90aGVzaXMgaXMgZGVmaW5lZCB0byBiZQ0KDQokJA0KVFMgPSBcZnJhY3tcaGF0e1xiZXRhfS0xfXtcaGF0e1xzaWdtYX1fMi9cc3FydHtufX0gXHNpbSBOKDAsIDEpLg0KJCQNCg0KVGhlIHAtdmFsdWUgb2YgdGhlIGFib3ZlIHR3by10YWlsIHRlc3QgaXMgDQoNCiQkDQpcdGV4dHtwLXZhbHVlfSA9IFBbWiA+IHxUU3wgXSwgXCBcIFx0ZXh0eyB3aGVyZSB9IFwgWiAgXCBcdGV4dHsgaXMgdGhlIHN0YW5kYXJkIG5vcm1hbCByYW5kb20gdmFyaWFibGUufQ0KJCQNCg0KSWYgdGhlIHAtdmFsdWUgaXMgbGVzcyB0aGFuIGEgdGhyZXNob2xkIChmb3IgZXhhbXBsZSAwLjA1KSwgdGhlIG51bGwgaHlwb3RoZXNpcyBpcyByZWplY3RlZC4gVGhlIG9uZS1wYXJhbWV0ZXIgZXhwb25lbnRpYWwgZGlzdHJpYnV0aW9uIHNob3VsZCBiZSB1c2VkLg0KDQoNCioqRXhhbXBsZSAoY29udGludWVkKSoqOiANCg0KSW4gdGhlIGFib3ZlIG51bWVyaWNhbCBleGFtcGxlIGFzc3VtaW5nIFdlaWJ1bGwgZGlzdHJpYnV0aW9uLCB3ZSB3YW50IHRvIHNlZSB3aGV0aGVyIGFuIGV4cG9uZW50aWFsIGhhcyBhIGJldHRlciBmaXQuIFRoaXMgaXMgZXF1aXZhbGVudCB0byB0ZXN0aW5nDQoNCiQkDQpcbWF0aGJie0h9XzA6IFwgXCBcYmV0YSA9IDEgXCBcIFx0ZXh0eyAgdi5zLiB9IFwgXCBcbWF0aGJie0h9X2E6IFwgXCBcYmV0YSBcbmUgMS4NCiQkDQoNClRoZSB0ZXN0IHN0YXRpc3RpYyBpcw0KDQokJA0KVFMgPSBcZnJhY3swLjg4OTYxNzggLSAxfXtcc3FydHswLjQxNDk1NjMvNDV9fSA9IC0xLjE0OTQ4Nw0KJCQNClRoZSBwLXZhbHVlIGlzDQoNCiQkDQpcdGV4dHtwLXZhbHVlfSA9IFAoWj58LTEuMTQ5NDg3fCkgPSAyXHRpbWVzIFAoWj4tMS4xNDk0ODcpIFxhcHByb3ggMC4yNTAzNTUyLg0KJCQNCg0KVGhlIG51bGwgaHlwb3RoZXNpcyBpcyAqKnJlamVjdGVkKiouIFRoaXMgaW1wbGllcyB0aGF0IFdlaWJ1bGwgZGlzdHJpYnV0aW9uIGlzIG1vcmUgYXBwcm9wcmlhdGUgdGhhbiBleHBvbmVudGlhbC4NCg0KXA0KDQoqKlJlbWFya3MqKjoNCg0KMS4gVGhlIGFib3ZlIHRlc3QgaXMgYmFzZWQgb24gdGhlIGFzc3VtcHRpb24gb2YgYSBsYXJnZSBzYW1wbGUuIA0KDQoyLiBTaW5jZSBUUyBpcyBhIHN0YW5kYXJkIG5vcm1hbCBkaXN0cmlidXRpb24uICRUU14yJCBpcyBhICRcY2hpXjJfMSQgZGlzdHJpYnV0aW9uLiBUaGF0IGlzLA0KDQokJA0KVyA9IFxsZWZ0W1xmcmFje1xoYXR7XGJldGF9LTF9e1xoYXR7XHNpZ21hfV8yL1xzcXJ0e259fVxyaWdodF1eMiBcc2ltIFxjaGleMl8xLg0KJCQNCg0KJFckIGlzIGNhbGxlZCAqKldhbGQqKiBzdGF0aXN0aWMuIFRoZSB0ZXN0IGlzIGNhbGxlZCB0aGUgKipXYWxkIFRlc3QqKi4NCg0KKipFeGFtcGxlIChjb250aW51ZWQpKio6IA0KDQokJA0KVyA9IFxsZWZ0W1xmcmFje1xoYXR7XGJldGF9LTF9e1xzcXJ0e1xoYXR7XHNpZ21hfV8yXjIvbn19XHJpZ2h0XV4yID0gXGxlZnRbXGZyYWN7MC44ODk2MTc4IC0gMX17XHNxcnR7MC40MTQ5NTYzLzQ1fX1ccmlnaHRdXjIgPSAoLTEuMTQ5NDg3KV4yID0gMS4zMjEzMi4NCiQkDQoNClRoZSBwLXZhbHVlIGJhc2VkIG9uIHRoZSBhYm92ZSBzdGF0aXN0aWMgaXMNCg0KJCQNClx0ZXh0e3AtdmFsdWV9ID0gUChcY2hpXjJfMSA+IDEuMzIxMzIpIFxhcHByb3ggMC4yNTAzNTUzLg0KJCQNCg0KDQoqKlJlbWFyayoqOiBBbGwgJFxjaGleMiQgdGVzdHMgYXJlIHJpZ2h0LXRhaWxlZCENCg0KXA0KDQoNCiMjIFNjb3JlIFRlc3QNCg0KQ29uc2lkZXIgdGhlIG51bGwgaHlwb3RoZXNpcw0KDQokJA0KSF8wOiBcIFwgXHRoZXRhID0gXHRoZXRhXzAuDQokJA0Kd2hpY2ggZGVmaW5lcyBhICoqcmVzdHJpY3RlZCBwYXJhbWV0ZXIgc3BhY2UqKi4gV2UgYWxzbyBuZWVkIHRoZSAqcmVzdHJpY3RlZCBNTEUqIGJlZm9yZSBkZWZpbmluZyB0aGUgdGVzdCBzdGF0aXN0aWMuIExldCANCg0KJCQNClx0aGV0YV97XHRleHR7ck1MRX19ID0gXGFyZ1xtYXhfe1x0aGV0YSBcaW4gXFRoZXRhX1J9XGxvZyBMKFx0aGV0YTpcbWF0aGJme3h9KS4NCiQkDQoNCldlIGhhdmUgc2hvd24gYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgc2VjdGlvbiB0aGF0IA0KDQokJA0KRVxsZWZ0WyBcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXHRoZXRhfSBcbG9nIEwoXHRoZXRhOlxtYXRoYmZ7eH0pIFxyaWdodF0gPSBcbWF0aGJmezB9LA0KJCQNCg0KYW5kDQoNCiQkDQpcbWF0aGJie0l9X24oXHRoZXRhKSA9IC1FXGxlZnRbXGxlZnQoXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsXHRoZXRhfVxsb2cgTChcdGhldGEsIFxtYXRoYmZ7eH0pXHJpZ2h0KVxsZWZ0KFxmcmFje1xwYXJ0aWFsfXtccGFydGlhbFx0aGV0YX1cbG9nIEwoXHRoZXRhLCBcbWF0aGJme3h9KVxyaWdodCleVCBccmlnaHRdDQokJA0KDQpXZSBhbHNvIHNob3dlZCB0aGF0DQoNCiQkDQpcdGV4dHt2YXJ9IFxsZWZ0W1xmcmFje1xwYXJ0aWFsfXtccGFydGlhbCBcdGhldGF9IFxsb2cgTChcdGhldGE6XG1hdGhiZnt4fSlccmlnaHRdID0gXG1hdGhiYntJfV9uKFx0aGV0YSkNCiQkDQoNCmFuZA0KDQokJA0KXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFx0aGV0YX0gXGxvZyBMKFx0aGV0YTpcbWF0aGJme3h9KSBccmlnaHRhcnJvd19wIFxtYXRoY2Fse059X2tcbGVmdFtcbWF0aGJmezB9LCBcbWF0aGJie0l9X24oXHRoZXRhKVxyaWdodF0NCiQkDQp3aGVyZSAkayA9IFxkaW0gKFxUaGV0YSkgLSBcZGltIChcVGhldGFfUikkLg0KDQpcDQoNCioqVGhlb3JlbSoqOiB3aXRoIHRoZSBhYm92ZSBub3RhdGlvbnMgYW5kIHNvbWUgcmVndWxhcml0eSBjb25kaXRpb25zLCB0aGUgZm9sbG93aW5nIGFzeW1wdG90aWMgbm9ybWFsaXR5IGhvbGRzLg0KDQokJA0KU19uID0gXGxlZnRbXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsXHRoZXRhfVxsb2cgTChcdGhldGFfe1x0ZXh0e3JNTEV9fSwgXG1hdGhiZnt4fSlccmlnaHRdXlQgXG1hdGhiYntJfV9uXnstMX0oXHRoZXRhX3tcdGV4dHtyTUxFfX0pXGxlZnRbXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsXHRoZXRhfVxsb2cgTChcdGhldGFfe1x0ZXh0e3JNTEV9fSwgXG1hdGhiZnt4fSlccmlnaHRdIFxyaWdodGFycm93X3AgXGNoaV4yX2ssDQokJA0KDQp3aGVyZSAkXHRoZXRhX3tcdGV4dHtyTUxFfX0kIGlzIHRoZSByZXN0cmljdGVkIE1MRSB1bmRlciB0aGUgbnVsbCBoeXBvdGhlc2lzLg0KDQoNCioqRXhhbXBsZSAoY29udGludWVkKSoqOiBUaGUgV2VpYnVsbCBleGFtcGxlIHJldmlzaXRlZC4gV2Ugc3RpbGwgY29uc2lkZXIgDQoNCiQkDQpIXzA6IFwgXCBcYmV0YSA9IDEgXCBcIFx0ZXh0e3ZzfSBcIFwgSF9hOiBcYmV0YSBcbmUgMS4NCiQkDQoNClVuZGVyICRIXzA6IFwgXCBcYmV0YSA9IDEkLCB0aGUgV2VpYnVsbCBkaXN0cmlidXRpb24gaXMgcmVkdWNlZCB0byB0aGUgZXhwb25lbnRpYWwgZGlzdHJpYnV0aW9uIHdpdGggZGVuc2l0eSAkZih4KSA9IFxhbHBoYSBlXnstXGFscGhhIHh9JC4gVGhlcmVmb3JlLCB0aGUgcmVzdHJpY3RlZCBNTEUgaXMgJFx0aGV0YV97XHRleHR7ck1MRX19ID0gKFxoYXR7XGFscGhhfSwgXGJldGE9MSkgPSAoMS9cYmFye3h9LDEpJC4NCg0KDQpUbyBkZWZpbmUgdGhlIHNjb3JlIHRlc3Qgc3RhdGlzdGljLCB3ZSBuZWVkIHRvIGZpbmQgdGhlIGdyYWRpZW50IHZlY3RvciBhbmQgdGhlIEZpc2hlciBpbmZvcm1hdGlvbiBtYXRyaXggYmFzZWQgb24gdGhlIHVucmVzdHJpY3RlZCBwYXJhbWV0ZXIgc3BhY2UuDQoNClRoZSBsb2ctbGlrZWxpaG9vZCBmdW5jdGlvbiBpcw0KDQokJA0KbChcYWxwaGEsIFxiZXRhKSA9IG5bXGxvZyhcYWxwaGEpICsgXGxvZyAoXGJldGEpXSArIChcYmV0YSAtMSlcc3VtX3tpPTF9Xm5cbG9nICh4X2kpLVxhbHBoYVxzdW1fe2k9MX1ebiB4X2leXGJldGENCiQkDQoNClRoZSBzY29yZSBmdW5jdGlvbnMgYXJlIGdpdmVuIGJ5DQoNCiQkDQpcYmVnaW57Y2FzZXN9IA0KXGZyYWN7XHBhcnRpYWwgbChcYWxwaGEsIFxiZXRhKX17XHBhcnRpYWwgXGFscGhhfSA9IFxmcmFje259e1xhbHBoYX0gLSBcc3VtX3tpPTF9Xm4geF9pXlxiZXRhLCAgICBcXCANClxmcmFje1xwYXJ0aWFsIGwoXGFscGhhLCBcYmV0YSl9e1xwYXJ0aWFsIFxiZXRhfT0gXGZyYWN7bn17XGJldGF9ICsgXHN1bV97aT0xfV5uIFxsb2coeF9pKSAtIFxhbHBoYSBcc3VtX3tpPTF9Xm4geF9pXlxiZXRhIFxsb2coeF9pKS4NClxlbmR7Y2FzZXN9IA0KJCQNCg0KYGBge3J9DQp4PSBjKDAuMiwgMC4zLCAwLjUsIDAuNSwgMC41LCAwLjUsIDAuNiwgMC42LCAwLjcsIDAuNywgMC43LCAwLjgsIDAuOCwgMS4wLCAxLjAsIDEuMCwgMS4wLCANCiAgICAgMS4xLCAxLjMsIDEuNSwgMS41LCAxLjUsIDEuNSwgMi4wLCAyLjAsIDIuMiwgMi41LCAzLjAsIDMuMCwgMy4zLCAzLjMsIDQuMCwgNC4wLCA0LjUsIA0KICAgICA0LjcsIDUuMCwgNS40LCA1LjQsIDcuMCwgNy41LCA4LjgsIDkuMCwgMTAuMywgMjIuMCwgMjQuNSkNCm4gPSBsZW5ndGgoeCkNCiMjDQpsYiA9IG4gKyBzdW0obG9nKHgpKSAtICgxL21lYW4oeCkpKnN1bSh4KmxvZyh4KSkNCmxiDQpgYGANCg0KVGhlIFNjb3JlIHZlY3RvciBpcw0KDQokJA0KVShcdGhldGFfe1x0ZXh0e3JNTEV9fSkgPSBcbGVmdFsgMCwgLTExLjEyNzE5IFxyaWdodF0NCiQkDQphbmQNCg0KJCQNClxmcmFje1xwYXJ0aWFsXjJ9e1xwYXJ0aWFsIFxhbHBoYV4yfVxsb2cgTChcYWxwaGE6XG1hdGhiZnt4fSkgPSAtXGZyYWN7bn17XGFscGhhXjJ9LCBcIFwgXHRleHR7YW5kfSBcIFwgIFxmcmFje1xwYXJ0aWFsXjJ9e1xwYXJ0aWFsIFxhbHBoYSBccGFydGlhbCBcYmV0YX1cbG9nIEwoXGFscGhhOlxtYXRoYmZ7eH0pID0gLVxzdW1fe2k9MX1ebiB4X2leXGJldGEgXGxvZyh4X2kpDQokJA0KDQokJA0KXGZyYWN7XHBhcnRpYWxeMn17XHBhcnRpYWwgXGJldGFeMn1cbG9nIEwoXGFscGhhOlxtYXRoYmZ7eH0pID0gLVxmcmFje259e1xiZXRhXjJ9IC1cc3VtX3tpPTF9Xm4geF9pXlxiZXRhIFxsb2coeF9pKQ0KJCQNCg0KYGBge3J9DQojIyBJbnZlcnNlIG9ic2VydmVkIEZpc2hlciBJbmZvcm1hdGlvbiBtYXRyaXgNCng9IGMoMC4yLCAwLjMsIDAuNSwgMC41LCAwLjUsIDAuNSwgMC42LCAwLjYsIDAuNywgMC43LCAwLjcsIDAuOCwgMC44LCAxLjAsIDEuMCwgMS4wLCAxLjAsIA0KICAgICAxLjEsIDEuMywgMS41LCAxLjUsIDEuNSwgMS41LCAyLjAsIDIuMCwgMi4yLCAyLjUsIDMuMCwgMy4wLCAzLjMsIDMuMywgNC4wLCA0LjAsIDQuNSwgDQogICAgIDQuNywgNS4wLCA1LjQsIDUuNCwgNy4wLCA3LjUsIDguOCwgOS4wLCAxMC4zLCAyMi4wLCAyNC41KQ0KbiA9IGxlbmd0aCh4KQ0KIyMNCmxhYSA9IC1uKm1lYW4oeCkNCmxhYiA9IC1zdW0oeCpsb2coeCkpDQpsYmIgPSAtbi1zdW0oeCpsb2coeCkpDQpJSW4gPSBtYXRyaXgoYyhsYWEsIGxhYiwgbGFiLCBsYmIpLCBucm93PTIpDQpJSW4uaW52ID0gc29sdmUoSUluKQ0KSUluLmludg0KYGBgDQoNClRoZSBvYnNlcnZlZCBGaXNoZXIgaW5mb3JtYXRpb24gbWF0cml4IGJhc2VkIG9uIHRoZSByZXN0cmljdGVkIE1MRSBpcyBnaXZlbiBieQ0KDQokJA0KXG1hdGhiYntJfV9uXnstMX0oXHRoZXRhX3tcdGV4dHtyTUxFfX0pID0gDQogICAgXGJlZ2lue2JtYXRyaXh9DQogICAgICAgMC4wMDkzMTk4ODkgJiAtMC4wMDgxMzc3OTUgXFwNCiAgICAgICAtMC4wMDgxMzc3OTUgJiAwLjAwNDI4NzA2MiANCiAgICBcZW5ke2JtYXRyaXh9ICAgICAgDQokJA0KDQoNCmBgYHtyfQ0KIyMgU2NvcmUgdGVzdCBzdGF0aXN0aWMNClNuPWMoMCwgLTExLjEyNzE5KSUqJSBJSW4uaW52ICUqJSBjKCAwLCAtMTEuMTI3MTkpDQpTbg0KYGBgDQoNClRoZSBzY29yZSB0ZXN0IHN0YXRpc3RpYyBpcw0KDQokJA0KU19uID0gWzAsIC0xMS4xMjcxOV1cYmVnaW57Ym1hdHJpeH0NCiAgICAgICAwLjAwOTMxOTg4OSAmIC0wLjAwODEzNzc5NSBcXA0KICAgICAgIC0wLjAwODEzNzc5NSAmIDAuMDA0Mjg3MDYyIA0KICAgIFxlbmR7Ym1hdHJpeH0NCiAgICBcYmVnaW57Ym1hdHJpeH0NCiAgICAgICAwICBcXA0KICAgICAgIC0xMS4xMjcxOQ0KICAgIFxlbmR7Ym1hdHJpeH0gXGFwcHJveCAwLjUzMDc5OTguDQokJA0KDQpTaW5jZSAkU19uIFxyaWdodGFycm93X3AgXGNoaV4yXzEkLiBUaGUgcC12YWx1ZSBvZiB0aGUgc2NvcmUgdGVzdCBpcyBnaXZlbiBieQ0KDQokJA0KXHRleHR7cC12YWx1ZX0gPSBQW1xjaGleMl8xID4gMC41MzA3OTk4XSA9IDAuNDY2MjcwOC4NCiQkDQoNClRoZSBudWxsIGh5cG90aGVzaXMgJEhfMDogXGJldGEgPSAxJCBpcyBub3QgcmVqZWN0ZWQuIFRoaXMgaXMgY29uc2lzdGVudCB3aXRoIHRoZSBXYWxkICRcY2hpXjIkIHRlc3QuDQoNCg0KDQoNClwNCg0KIyMgTGlrZWxpaG9vZCBSYXRpbyBUZXN0IChMUlQpDQoNClRoZSBsaWtlbGlob29kIHJhdGlvIChMUikgdGVzdCANCg0KVGhlIGxpa2VsaWhvb2QgcmF0aW8gdGVzdCBpcyBvbmUgb2YgdGhlIG1vc3QgY29tbW9ubHkgdXNlZCBpbiBsaWtlbGlob29kLWJhc2VkIHN0YXRpc3RpY2FsIGluZmVyZW5jZXMuIEl0IGlzIGEgdGVzdCBvZiBoeXBvdGhlc2lzIGluIHdoaWNoIHR3byBkaWZmZXJlbnQgbWF4aW11bSBsaWtlbGlob29kIGVzdGltYXRlcyBvZiBhIHBhcmFtZXRlciBhcmUgY29tcGFyZWQgaW4gb3JkZXIgdG8gZGVjaWRlIHdoZXRoZXIgdG8gcmVqZWN0IG9yIG5vdCB0byByZWplY3QgYSAqKnJlc3RyaWN0aW9uIG9uIHRoZSBwYXJhbWV0ZXIqKiAoc3VjaCBhcyBzZXR0aW5nICRcYmV0YSA9IDEkIGluIHRoZSBwcmV2aW91cyBXZWlidWxsIGRpc3RyaWJ1dGlvbikuDQoNClRoaXMgbm90ZSBmb2N1c2VzIG9uIHBhcmFtZXRyaWMgbGlrZWxpaG9vZCBpbmZlcmVuY2VzLiBUaGUgTFJUIGlzIHVzZWQgdG8gY29tcGFyZSB0d28gbmVzdGVkIG1vZGVscy4gVGhlIGJhc2ljIHNldHVwIGlzIG91dGxpbmVkIGluIHRoZSBmb2xsb3dpbmcuDQoNCkluIGVzc2VuY2UsIHRoZSBMUlQgaXMgYmFzZWQgb24gdHdvIE1MRXMgZnJvbSB0d28gcGFyYW1ldGVyIHNwYWNlczogKipmdWxsIHBhcmFtZXRlciBzcGFjZSAoJFxUaGV0YSQpKiogYW5kICoqcmVzdHJpY3RlZCBwYXJhbWV0ZXIgc3BhY2UgJFxUaGV0YV97Un0kKiouDQoNCiogKipGdWxsIChVbnJlc3RyaWN0ZWQpIFBhcmFtZXRlciBTcGFjZSoqOiBUaGUgcGFyYW1ldGVyIHNwYWNlIGNvbnRhaW5pbmcgYWxsIHZhbHVlcyB0aGF0IHRoZSBwYXJhbWV0ZXIgdmVjdG9yIGNhbiB0YWtlLiBGb3IgZXhhbXBsZSwgZm9yIG5vcm1hbCBkaXN0cmlidXRpb24gd2l0aCBkZW5zaXR5ICROKFxtdSwgXHNpZ21hKSQsICRcbXUgXGluIFxtYXRoYmJ7Un0kIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gJFxzaWdtYSBcaW4gXG1hdGhiYntSfV4rJCwgdGhlbiAkXFRoZXRhIFxzdGFja3JlbHtcdGV4dHtkZWZ9fXtcZXF1aXZ9IFxtYXRoYmJ7Un1cdGltZXMgXG1hdGhiYntSfV4rJCBpcyB0aGUgcGFyYW1ldGVyIHNwYWNlIG9mICRcdGhldGEgPSBjKFxtdSwgXHNpZ21hKSQuIA0KDQoqICoqUmVzdHJpY3RlZCBQYXJhbWV0ZXIgU3BhY2UqKjogQSBzdWJzcGFjZSBvZiB0aGUgdW5yZXN0cmljdGVkIHNwYWNlLiBGb3IgZXhhbXBsZSwgaW4gdGhlIDItcGFyYW1ldGVyIFdlaWJ1bGwgZGlzdHJpYnV0aW9uLCB0aGUgcGFyYW1ldGVyIHNwYWNlIGlzICRcVGhldGEgPSBcbWF0aGJie1J9XitcdGltZXMgXG1hdGhiYntSfV4rJCBiZWNhdXNlIGJvdGggcGFyYW1ldGVycyAoJFxhbHBoYSwgXGJldGEkKSBhcmUgcG9zaXRpdmUuICBUaGF0IGlzLCAkXFRoZXRhJCBpcyBzcGFubmVkIGJ5ICQoXGFscGhhLCBcYmV0YSkkLiBJZiB3ZSBzZXQgJFxiZXRhID0gMSQsICQoXGFscGhhLCAxKSQgc3BhbnMgdGhlIHJlc3RyaWN0ZWQgcGFyYW1ldGVyIHNwYWNlICRcVGhldGFfUiA9IFxtYXRoYmJ7Un1eK1x0aW1lcyBcezFcfSQuDQoNCg0KYGBge3IgZWNobz1GQUxTRSwgZmlnLmFsaWduID0iY2VudGVyIiwgIG91dC53aWR0aCA9ICc5MCUnLCBmaWcuY2FwPSJQYXJhbWV0ZXIgc3BhY2VzIG9mIDItcGFyYW1ldGVyIFdlaWJ1bGwgZGlzdHJpYnV0aW9uIn0NCmluY2x1ZGVfZ3JhcGhpY3MoImltZy93MDUtUmVzdHJpY3RlZFVucmVzdHJpY3RlZFNwYWNlcy5wbmciKQ0KYGBgDQoNCg0KDQoqICoqVW5yZXN0cmljdGVkIGFuZCBSZXN0cmljdGVkIE1heGltdW0gTGlrZWxpaG9vZCoqOiBUaGUgdW5yZXN0cmljdGVkIG1heGltdW0gbGlrZWxpaG9vZCBpcyBiYXNlZCBvbiB0aGUgdW5yZXN0cmljdGVkIHBhcmFtZXRlciBzcGFjZSAoJFxUaGV0YSQpIGFuZCB0aGUgcmVzdHJpY3RlZCBtYXhpbXVtIGxpa2VsaWhvb2QgaXMgYmFzZWQgb24gdGhlIHJlc3RyaWN0ZWQgcGFyYW1ldGVyIHNwYWNlICgkXFRoZXRhX1IkKS4gVGhlIHVucmVzdHJpY3RlZCBhbmQgcmVzdHJpY3RlZCBNTEVzIGFyZSBnaXZlbiBieQ0KDQokJA0KXGhhdHtcdGhldGF9X3tNTEV9ID0gXGFyZ1xtYXhfe1x0aGV0YVxpbiBcVGhldGF9IFxsb2cgTChcdGhldGE6IFxtYXRoYmZ7eH0pDQokJA0KDQphbmQgDQoNCiQkDQpcaGF0e1x0aGV0YX1fe3JNTEV9ID0gXGFyZ1xtYXhfe1x0aGV0YVxpbiBcVGhldGFfUn0gXGxvZyBMKFx0aGV0YTogXG1hdGhiZnt4fSkNCiQkDQoNCldpdGggdGhlIGFib3ZlIG5vdGF0aW9ucywgd2Ugc3RhdGUgdGhlIGZvbGxvd2luZyB0aGVvcmVtLiBUaGUgcHJvb2YgaXMgb3V0IG9mIHRoZSBzY29wZSBvZiB0aGlzIHNlcmllcyBvZiB0dXRvcmlhbHMuDQoNCioqVGhlb3JlbSoqOiBMZXQgJFxoYXR7XHRoZXRhfV97XHRleHR7TUxFfX0kIGFuZCAkXGhhdHtcdGhldGF9X3tcdGV4dHtyTUxFfX0kIGJlIHRoZSB1bnJlc3RyaWN0ZWQgTUxFIGFuZCByZXN0cmljdGVkIE1MRSBlc3RpbWF0ZWQgYmFzZWQgb24gJFxUaGV0YSQgYW5kICRcVGhldGFfUiQgcmVzcGVjdGl2ZWx5LiBEZW5vdGUgJFx0ZXh0e2RmfSA9IFxkaW0oXFRoZXRhKSAtIFxkaW0oXFRoZXRhX1IpJCwgdGhlbg0KdGhlIHRlc3Qgc3RhdGlzdGljIGZvciB0ZXN0aW5nIHRoZSBudWxsIGh5cG90aGVzaXMNCg0KJCQNCkhfe1x0ZXh0ezB9fTogXHRoZXRhXzAgXGluIFxUaGV0YV9SDQokJA0KDQppcyBkZWZpbmVkIHRvIGJlIA0KDQokJA0KTFJUPS0yXGxuIFxmcmFje0woXGhhdHtcdGhldGF9X3tyTUxFfTpcbWF0aGJme3h9KX17TChcaGF0e1x0aGV0YX1fe01MRX06XG1hdGhiZnt4fSl9IFxyaWdodGFycm93X3BcY2hpXjJfe1x0ZXh0e2RmfS59DQokJA0KVGhlIHAtdmFsdWUgb2YgdGhlIGFib3ZlIGxpa2VsaWhvb2QgcmF0aW8gJFxjaGleMiQgdGVzdCBpcyBkZXRlcm1pbmVkIGJ5DQoNCiQkDQpcdGV4dHtwLXZhbHVlfSA9IFAoXGNoaV4yX3tcdGV4dHtkZn19ID4gTFJUKS4NCiQkDQpcDQoNCjxmb250IGNvbG9yID0gInJlZCI+KipcY29sb3J7cmVkfVJlY2FwIG9mIExSVCoqPC9mb250Pg0KDQpUaGUgbGlrZWxpaG9vZCByYXRpbyAkXGNoaV4yJCB0ZXN0IGludm9sdmVzIHRocmVlIHRlY2huaWNhbCBzdGVwczoNCg0KMS4gRmluZCB0aGUgTUxFIG9mIHRoZSBwYXJhbWV0ZXJzIGluIHRoZSByZXN0cmljdGVkIHBhcmFtZXRlciBzcGFjZSAoJFxtYXRoYmJ7XFRoZXRhfV9SJCkgd2hpY2ggaXMgZGVmaW5lZCBiYXNlZCBvbiB0aGUgbnVsbCBoeXBvdGhlc2lzICRIXzAkLg0KDQoNCjIuIEZpbmQgdGhlIE1MRSBvZiB0aGUgcGFyYW1ldGVycyBpbiB0aGUgdW5yZXN0cmljdGVkIHBhcmFtZXRlciBzcGFjZSAoJFxtYXRoYmJ7XFRoZXRhfSQpLg0KDQoNCjMuIEV2YWx1YXRlIHRoZSBsaWtlbGlob29kIHJhdGlvIHN0YXRpc3RpYyBhbmQgZmluZCB0aGUgcC12YWx1ZSBiYXNlZCBvbiB0aGUgcmVzdWx0aW5nICRcY2hpXjJfe1x0ZXh0e2RmfX0kIHdpdGggJFx0ZXh0e2RmfSA9IFx0ZXh0e2RpbX0gKFxtYXRoYmJ7XFRoZXRhfSktIFx0ZXh0e2RpbX0gKFxtYXRoYmJ7XFRoZXRhfV9SKSQuIA0KDQoNCg0KKipFeGFtcGxlIChXZWlidWxsIGV4YW1wbGUgcmV2aXNpdGVkKSoqOiBXZSB3aWxsIGZvbGxvdyB0aGUgYWJvdmUgdGhyZWUgdGVjaG5pY2FsIHN0ZXBzIGZvciB0ZXN0aW5nIHRoZSBudWxsIGh5cG90aGVzaXMNCg0KJCQNCkhfMDogXGJldGEgPSAxIFwgXCBcdGV4dHsgdnMgfSBcIFwgSF9hOiBcYmV0YSBcbmUgMS4gDQokJA0KDQpOb3RlIHRoYXQgJEhfMCQgZGVmaW5lcyB0aGUgcmVzdHJpY3RlZCBzcGFjZSAkXG1hdGhiYntcVGhldGF9X1IgPSBcbWF0aGJie1J9XisgXHRpbWVzIHsxfSQuIFdlIG5lZWQgdG8gZmluZCBhIHZhbHVlIGZyb20gYWxsIHBvc3NpYmxlIHZhbHVlcyBvZiAkXGFscGhhJCBnaXZlbiAkXGJldGEgPSAxJCB0aGF0IG1heGltaXplcyB0aGUgbG9nLWxpa2VsaWhvb2Qgb2Ygb2JzZXJ2aW5nIHRoZSBkYXRhLiANCg0KKlN0ZXAgMSo6IEZpbmQgdGhlIHJlc3RyaWN0ZWQgTUxFIGlzIHRoZSBNTEUgb2YgZXhwb25lbnRpYWwgZGlzdHJpYnV0aW9uIHdpdGggZGVuc2l0eSAkZih4LCBcYWxwaGEpID0gXGFscGhhIGVeey1cYWxwaGEgeH0kLg0KDQpXZSBrbm93IHRoZSBzb2x1dGlvbiB0byB0aGUgb3B0aW1pemF0aW9uIHByb2JsZW0gaGFzIGEgY2xvc2VkIGZvcm0gJFxoYXR7XGFscGhhfSA9IG4vXHN1bV97aT0xfV5uIHhfaSA9IDQ1LzE2My4yIFxhcHByb3ggMC4yNzU3MzUzJC4gVGhhdCBpcywgcmVzdHJpY3RlZCBNTEUgJFx0aGV0YV97ck1MRX0gPSAwLjI3NTczNTMkLiBUaGUgbG9nLWxpa2VsaWhvb2QgZXZhbHVhdGVkIGF0IHRoZSByZXN0cmljdGVkIE1MRSBpcyBnaXZlbiBieQ0KDQokJA0KXGxvZyBMKFxoYXR7XHRoZXRhfV97ck1MRX0sIFxtYXRoYmZ7eH0pID0gblxsb2coYSkgLSBhXHN1bV97aT0xfV57NDV9eF9pDQokJA0KDQokJA0KPTQ1XGxvZygwLjI3NTczNTMpLTAuMjc1NzM1M1x0aW1lcyAxNjMuMiA9IC0xMDIuOTc0MS4NCiQkDQoNClRoZSBsb2ctbGlrZWxpaG9vZCBjdXJ2ZSBhbmQgaXRzIGNyaXRpY2FsIHBvaW50IGlzIGdpdmVuIGluIHRoZSBmaWd1cmUgYmVsb3cuDQoNCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00LCBmaWcuY2FwPSJsb2ctbGlrZWxpaG9vZCBjdXJ2ZSB3aXRoIGNyaXRpY2FsIHBvaW50IGxhYmVsZWQgaW4gcmVkLiJ9DQojIERhdGEgc2V0DQp4ID0gYygwLjIsIDAuMywgMC41LCAwLjUsIDAuNSwgMC41LCAwLjYsIDAuNiwgMC43LCAwLjcsIDAuNywgMC44LCAwLjgsIDEuMCwgMS4wLCAxLjAsIDEuMCwgDQogICAgICAxLjEsIDEuMywgMS41LCAxLjUsIDEuNSwgMS41LCAyLjAsIDIuMCwgMi4yLCAyLjUsIDMuMCwgMy4wLCAzLjMsIDMuMywgNC4wLCA0LjAsIDQuNSwgDQogICAgICA0LjcsIDUuMCwgNS40LCA1LjQsIDcuMCwgNy41LCA4LjgsIDkuMCwgMTAuMywgMjIuMCwgMjQuNSkNCm4gPSBsZW5ndGgoeCkNCiMjIGxvZy1saWtlbGlob29kDQpuZWdMb2dMaWsgPSBmdW5jdGlvbihhKXsNCiAgYiA9IDENCiAgbipsb2coYSkgLSBhKnN1bSh4XmIpDQp9DQojIyBncmFkaWVudCBmdW5jdGlvbg0KIyMgV2UgZmlyc3QgcGxvdCB0aGUgbG9nLWxpa2VsaWhvb2QgZnVuY3Rpb24NCmFscGhhID0gc2VxKDAuMDEsIDEsIGxlbmd0aD0xMDApDQpsZ2xpayA9IG5lZ0xvZ0xpayhhbHBoYSkNCnBsb3QoYWxwaGEsIGxnbGlrLCB0eXBlPSJsIiwgIHlsYWIgPSJMb2dsaWtlbGlob29kIikNCmFibGluZSh2PTAuMjc1NzM1MywgY29sPSJyZWQiKQ0KcG9pbnRzKDAuMjc1NzM1MywgbmVnTG9nTGlrKDAuMjc1NzM1MyksIHBjaD0xOSwgY29sID0gInJlZCIsIGNleCA9IDEuNSkNCnRleHQoMC41LCAtMTUwLCAiKDAuMjc1NywgLTEwMy4wKSIsIGNvbD0iYmx1ZSIpDQphcnJvd3MoMC4yNzU3LCBuZWdMb2dMaWsoMC4yNzU3MzUzKSwgMC41LCAtMTQ1LCBsZW5ndGggPSAwLjA1LCBhbmdsZSA9IDMwLA0KICAgICAgIGNvZGUgPSAyKQ0KYGBgDQoNCipTdGVwIDIqOiBsb2ctbGlrZWxpaG9vZCBldmFsdWF0ZWQgYXQgdW5yZXN0cmljdGVkIE1MRS4NCg0KVGhlIHVucmVzdHJpY3RlZCBNTEUgaGFzIGZvdW5kIGluIHRoZSBwcmV2aW91cyBleGFtcGxlICRcaGF0e1x0aGV0YX1fe01MRX0gPShcaGF0e1xhbHBoYX0sIFxoYXR7XGJldGF9KSBcYXBwcm94ICgwLjMzNzcyNzEsIDAuODg5NjE1OSkkLiBUaGUgbG9nLWxpa2VsaWhvb2QgZXZhbHVhdGVkIGF0ICQoXGhhdHtcYWxwaGF9LCBcaGF0e1xiZXRhfSkgXGFwcHJveCAoMC4zMzc3MjcxLCAwLjg4OTYxNTkpJCBpcw0KDQokJA0KXGxvZyBMKFxoYXR7XHRoZXRhfTogXG1hdGhiZnt4fSkgPSBuXGxvZyhcYWxwaGEpICsgblxsb2coXGJldGEpICsgKFxiZXRhLTEpXHN1bV97aT0xfV5uXGxvZyh4X2kpIC0gXGFscGhhXHN1bV97aT0xfV5uKHhfaV5cYmV0YSkNCiQkDQoNCg0KYGBge3J9DQojIERhdGEgc2V0DQp4ID0gYygwLjIsIDAuMywgMC41LCAwLjUsIDAuNSwgMC41LCAwLjYsIDAuNiwgMC43LCAwLjcsIDAuNywgMC44LCAwLjgsIDEuMCwgMS4wLCAxLjAsIDEuMCwgDQogICAgICAxLjEsIDEuMywgMS41LCAxLjUsIDEuNSwgMS41LCAyLjAsIDIuMCwgMi4yLCAyLjUsIDMuMCwgMy4wLCAzLjMsIDMuMywgNC4wLCA0LjAsIDQuNSwgDQogICAgICA0LjcsIDUuMCwgNS40LCA1LjQsIDcuMCwgNy41LCA4LjgsIDkuMCwgMTAuMywgMjIuMCwgMjQuNSkNCm4gPSBsZW5ndGgoeCkNCiMjIGxvZy1saWtlbGlob29kDQpuZWdMb2dMaWsgPSBmdW5jdGlvbihBKXsNCiAgYSA9IEFbMV0NCiAgYiA9IEFbMl0NCiAgbipsb2coYSkgKyBuKmxvZyhiKSArIChiLTEpKnN1bShsb2coeCkpIC0gYSpzdW0oeF5iKQ0KfQ0KIyAwLjMzNzcyNTkgMC44ODk2MTc4DQpBID0gYygwLjMzNzcyNTksIDAuODg5NjE3OCkNCmxnbGlrID0gbmVnTG9nTGlrKEEpDQpsZ2xpaw0KYGBgDQoNCipTdGVwIDMqOiBFdmFsdWF0aW5nIHRoZSBMUlQgYW5kIGZpbmRpbmcgdGhlIHAtdmFsdWUuDQoNCiQkDQpMUlQgPSAtMlxsb2cgXGZyYWN7TChcaGF0e1x0aGV0YX1fe3JNTEV9OiBcbWF0aGJme3h9KX17TChcaGF0e1x0aGV0YX1fe01MRX06IFxtYXRoYmZ7eH0pfT0tMlxsZWZ0W1xsb2cgTChcaGF0e1x0aGV0YX1fe3JNTEV9OiBcbWF0aGJme3h9KSAtIFxsb2cgTChcaGF0e1x0aGV0YX1fe01MRX06IFxtYXRoYmZ7eH0pIFxyaWdodF0gXHJpZ2h0YXJyb3dfcCBcY2hpXjJfMS4NCiQkDQoNClRoZSB2YWx1ZSBvZiB0aGUgYWJvdmUgdGVzdCBzdGF0aXN0aWMgaXMNCg0KJCQNCkxSVCA9IC0yWyAtMTAyLjk3NDEtICgtMTAyLjM0NTIpXSA9IDEuMjU3OC4NCiQkDQpUaGUgcC12YWx1ZSBvZiB0aGUgTFJUIHRlc3QgaXMgY2FsY3VsYXRlZCBpbiB0aGUgZm9sbG93aW5nDQoNCiQkDQpcdGV4dHtwLXZhbHVlfSA9IFBbXGNoaV4yXzE+MS4yNTc4XSA9IDAuNzM3OTMyMS4NCiQkDQoNClRoaXMgaW1wbGllcyB0aGF0IHRoZXJlIGlzIGFuIG92ZXJmaXQgaXNzdWUgaWYgd2UgY2hvb3NlIHRoZSB0d28tcGFyYW1ldGVyIFdlaWJ1bGwgZGlzdHJpYnV0aW9uIHRvIGZpdCB0aGUgZ2l2ZW4gZGF0YS4gVGhlIG9uZS1wYXJhbWV0ZXIgZXhwb25lbnRpYWwgaXMgYSBiZXR0ZXIgY2hvaWNlIGZvciB0aGlzIGFwcGxpY2F0aW9uLg0KDQoNCg0KDQojIyBDb25jbHVkaW5nIFJlbWFya3MNCg0KSW4gdGhpcyBzZWN0aW9uLCB3ZSBpbnRyb2R1Y2VkIHRocmVlIG1ham9yIGxhcmdlIHNhbXBsZSB0ZXN0cyBhc3NvY2lhdGVkIHdpdGggbGlrZWxpaG9vZCBlc3RpbWF0b3JzOiBXYWxkLCBTY29yZSwgYW5kIGxpa2VsaWhvb2QgcmF0aW8gdGVzdHMuIA0KDQpUaHJlZSBjaGktc3F1YXJlIHRlc3RzIGFyZSBhc3ltcHRvdGljYWxseSBlcXVpdmFsZW50LiBIb3dldmVyLCB0aGlzIHBvdGVudGlhbGx5IGdpdmVzIHRoZSB3cm9uZyBpbXByZXNzaW9uIHRoYXQgYWxsIHRocmVlIGFwcHJvYWNoZXMgYXJlIGVxdWFsbHkgYWNjdXJhdGUgcmVnYXJkaW5nIGFwcHJveGltYXRpb24gaW5mZXJlbmNlLg0KDQpNYW55IHN0dWRpZXMgaW4gdGhlb3J5IGFuZCBzaW11bGF0aW9uIGhhdmUgc2hvd24gdGhhdCB0aGUgbGlrZWxpaG9vZCByYXRpbyBhcHByb2FjaCBpcyB0aGUgbW9zdCBhY2N1cmF0ZSBhbW9uZyB0aGUgdGhyZWUgbGFyZ2Utc2FtcGxlIHRlc3RzLiANCg0KVGhlIFNjb3JlIGFuZCBXYWxkIGFwcHJvYWNoZXMgZGVwZW5kIG9uIGRlcml2YXRpdmVzLCBhbmQgdGh1cywgY2FuIGNoYW5nZSBzdWJzdGFudGlhbGx5IGlmIHdlIHJlcGFyYW1ldGVyaXplIHRoZSBtb2RlbC4gVGhlIGxpa2VsaWhvb2QgcmF0aW8gdGVzdCBpcyByZWNvbW1lbmRlZCBpbiBwcmFjdGljZS4gDQoNClRoZSBsaWtlbGlob29kIHJhdGlvIHRlc3QgcmVxdWlyZXMgcmVzdHJpY3RlZCBhbmQgdW5yZXN0cmljdGVkIE1MRXMgdGhhdCBkZWZpbmVkIGJhc2VkIG9uIHRoZSByZXN0cmljdGVkIGFuZCB1bnJlc3RyaWN0ZWQgcGFyYW1ldGVyIHNwYWNlcy4gPGZvbnQgY29sb3IgPSDigJxyZWTigJ0+XGNvbG9ye3JlZH1UaGlzIG1lYW5zIHRoYXQgdGhlIExSVCBjb21wYXJlcyBvbmx5IHR3byBuZXN0ZWQgbW9kZWxzIG9yIGRpc3RyaWJ1dGlvbnMuPC9mb250Pg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQo=